linux脚本自动化实现远程登陆操作和传输文件(scp ssh expect)

为实现脚本自动化 多服务器登陆操作并传输文件,网上查找了各种各样的资料,很多都有各种各样的坑 ,现在将自己完整实现分享出来,希望大家少点坑吧

1. 下载安装expect

linux expect 安装
Expect是在Tcl基础上创建起来的,它还提供了一些Tcl所没有的命令,它可以用来做一些linux下无法做到交互的一些命令操作,在远程管 理方面发挥很大的作用。
spawn命令激活一个Unix程序来进行交互式的运行。

send命令向进程发送字符串。

expect 命令等待进程的某些字符串。

expect支持正规表达式并能同时等待多个字符串,并对每一个字符串执行不同的操作.

A. Tcl 安装
主页: http://www.tcl.tk
下载地址: http://www.tcl.tk/software/tcltk/downloadnow84.tml

1.下载源码包
wget http://nchc.dl.sourceforge.net/sourceforge/tcl/tcl8.4.11-src.tar.gz

2.解压缩源码包
tar xfvz tcl8.4.11-src.tar.gz

3.安装配置

cd tcl8.4.11/unix
./configure --prefix=/usr/tcl --enable-shared
make
make install

安装完毕以后,进入tcl源代码的根目录,把子目录unix下面的tclUnixPort.h 复制到子目录generic中。

cp tclUnixPort.h ../generic/

暂时不要删除tcl源代码,因为expect的安装过程还需要用。

B. expect 安装 (需Tcl的库)
主页: http://expect.nist.gov/

1.下载源码包
wget http://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz

2.解压缩源码包
tar xzvf expect5.45.tar.gz

3.安装配置

cd expect5.45
./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=../tcl8.4.11/generic

make
make install
ln -s /usr/tcl/bin/expect /usr/expect/bin/expect
 软链接      源路径                  目标路径  

注意1:

/usr/expect/bin/expect 此路径为except脚本的启动路径(脚本第一行)

2. 脚本 单个远程scp任务传输

#!/usr/expect/bin/expect            
set timeout -1
set host [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
set src_file [lindex $argv 3]
set dest_file [lindex $argv 4]
spawn scp $src_file $username@$host:$dest_file     
 expect {
 "(yes/no)?"
  {
  send "yes\n"
  expect "*assword:" { send "$password\n"}
 }
 "*assword:"
{
 send "$password\n"
}
}
expect "100%"
expect eof

注意2: 连接远程电脑会提示需要输入密码,所以才要用脚本实现自动化处理

5个需要手动输入的参数,分别为:目标主机的IP、用户名、密码、本地文件路径、目标主机中的文件路径(目标路径可以写入新的文件名来达到重命名的效果,如果已存在就会覆盖。

第一行必须写入启动路径

3. batch_scp.sh脚本 批量远程scp任务传输

1.首先新建一个文件hosts.list
列表文件指定了远程主机ip、用户名、密码,这些信息需要写成以下的格式:
IP username password
中间用空格或tab键来分隔,多台主机的信息需要写多行内容

2.写batch_scp.sh脚本,在脚本中执行expet.scp脚本

#!/bin/sh
list_file=$1
src_file=$2
dest_file=$3
cat $list_file | while read line
do
   host_ip=`echo $line | awk '{print $1}'`
   username=`echo $line | awk '{print $2}'`
   password=`echo $line | awk '{print $3}'`
   echo "$host_ip"
   ./expect_scp $host_ip $username $password $src_file $dest_file
done

4. except_ssh 连接远程服务器并操作它执行sprintboot命令

#!/usr/expect/bin/expect
set timeout -1
set host [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
set pathName [lindex $argv 3]
set shellName  [lindex $argv 4]
spawn ssh ${host}
expect {
 "(yes/no)?"
  {
  send "yes\n"
  expect "*assword:" { send "$password\n"}
 }
 "*assword:"
{
 send "$password\n"
}
}
expect "login"

expect "*#*" { send "cd $pathName \r" }
expect "*#*" { send "./sprintboot   $shellName \r" }
expect "*#*" { send "logout\r" }
expect eof

5. 单个任务实现scp传输文件然后执行启动命令

#!/bin/sh
host_ip=$1
username=$2
password=$3
src_file=$4
dest_file=$5
pathName=$6
shellName=$7
   ./expect_scp $host_ip $username $password $src_file $dest_file
  ./expect_ssh  $host_ip $username $password $pathName $shellName

1.主机名
2.用户名
3.密码
4.源文件路径
5.目标服务器文件路径
6.sprintboot启动文件所在路径
7.要执行的命令名称


注意:

脚本最后一行要写上 exit 退出 一般写 exit 0

带端口号:

scp -P $port  $src_file $username@$host:$dest_file/boce.jar(大写的P)
ssh ${username}@${host} -p ${port}  (小写的p)

6. 参考资料

安装
https://www.cnblogs.com/daojian/archive/2012/10/10/2718390.html
scp脚本
http://www.jb51.net/article/34005.htm
https://www.cnblogs.com/jixingke/p/6213074.html
ssh登录
https://www.chenyudong.com/archives/expect-non-interactive-ssh-login-password-authentication.html

7. 项目中启动脚本的方式

package com.aodong.broadband.api.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;


public class ShellUtils {

    private static Logger logger = LoggerFactory.getLogger(ShellUtils.class);


    //远程传输文件
    public static int sendPb(String ip, String userName, String password, String scriptPath,String filePath) throws Exception {


        String target = "/home/script";
        // 执行脚本
        ProcessBuilder pb = new ProcessBuilder("./batch_scp.sh", ip, userName, password, filePath, target);
        //脚本路径
        pb.directory(new File(scriptPath));

        int runningStatus = 1;
        String s = null;
        //开始执行脚本内容
        Process p = pb.start();
        //执行最后一行脚本返回的值   一般是0
        runningStatus = p.waitFor();

        logger.info("runningStatus:{}", runningStatus);
        // 执行的内容
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line).append("\n");
        }
        String result = sb.toString();
        // 日志显示执行的内容过程
        logger.debug(result);
        br.close();
        return runningStatus;

    }

    //jar文件的开始,重启,停止
    public static int shShell(String ip, String userName, String password, String scriptPath, String start) throws Exception {



        String target = "/home/script";


        ProcessBuilder pb = new ProcessBuilder("./start.sh", ip, userName, password, target, start);

        pb.directory(new File(scriptPath));

        int runningStatus = 1;
        String s = null;
        Process p = pb.start();
        runningStatus = p.waitFor();
        logger.info("runningStatus:{}", runningStatus);
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line).append("\n");
        }
        String result = sb.toString();
        logger.debug(result);
        br.close();
        return runningStatus;
    }

}

你可能感兴趣的:(Linux)