linux使用shell脚本利用expect工具实现SCP传输文件到多台服务器

1、安装expect

yum install expect

2、设置服务器地址,用户名,密码,源路径,目标路径

新建文件host.txt添加如下内容

192.168.0.135 root 密码 源路径 目标路径
192.168.0.136 root 密码 源路径 目标路径
192.168.0.137 root 密码 源路径 目标路径
# 实例
192.168.128.133 root root /usr/local/shell/test1.txt /usr/local

3、添加expect执行脚本: cpExeShell.sh
用于读取服务器账号配置的host.txt进行调用执行scp登录传输 密码 + 服务器IP

#!/usr/bin/expect -f
set HOST [lindex $argv 0]
set USERNAME [lindex $argv 1]
set PASSWD [lindex $argv 2]
set source [lindex $argv 3]
set target [lindex $argv 4]
spawn scp -r $source $USERNAME@$HOST:$target
expect {
"(yes/no)?"
{
send "yes\n"
expect "*assword:" { send "$PASSWD\r" }
}
"*assword:"
{
send "$PASSWD\r"
}
}
expect eof

expect是一个阻塞的switch,spawn执行一个命令后,expect会匹配返回值,并执行相应的操作。
expect格式

	expect {
		"string"  #-re可以正则匹配字符串
			{
				command
			}
		status
			{
				command
			}
	}

(注意,expect右边必须有值,把括号写在下一行会报错!)
其中command可以是tcl语法命令,如puts,也可以是expect命令,如send,exp_continue,exit等等;而status是指expect的状态信息,如timeout,connected。

  set  赋值,sethost [lindex $argv0] 就是将参数0赋值给变量host,其中,[] 括起命令,执行括号内命令后返回结果,lindex是取列表中的某个参数,$argv则是参数列表。
     while { } {command} while循环,和bash类似,while后面要留一个空格,右括号后面再留一个空格,我就是在这里遇到了莫名的报错。。

4、添加shell脚本执行expect脚本:exeScp.sh

#!/bin/bash
dir=/home
while read line
do
host=`echo $line| awk '{print $1}'`
username=`echo $line | awk '{print $2}'`
passwd=`echo $line | awk '{print $3}'`
source=`echo $line | awk '{print $4}'`
target=`echo $line | awk '{print $5}'`
$dir/cpExeShell.sh $host $username $passwd $source $target 
done < $dir/host.txt

5、赋予sh文件执行权限

chmod +x *.sh

6、执行

./exeScp.sh

说明:此处有三个文件均在home文件夹下,如需要发送其它文件夹到目标服务器,只需更改或增加host.txt文件中内容即可。(一般复制到home目录因为这个目录对外有可执行权限)

文件保留:
host.txt

192.168.128.133 root root /usr/local/shell/test1.txt /usr/local

cpExeShell.sh

#!/usr/bin/expect -f
set HOST [lindex $argv 0]
set USERNAME [lindex $argv 1]
set PASSWD [lindex $argv 2]
set source [lindex $argv 3]
set target [lindex $argv 4]
spawn scp -r $source $USERNAME@$HOST:$target
expect {
"(yes/no)?"
{
send "yes\n"
expect "*assword:" { send "$PASSWD\r" }
}
"*assword:"
{
send "$PASSWD\r"
}
}
expect eof

exeScp.sh

#!/bin/bash
dir=/usr/local/shell
while read line
do
host=`echo $line| awk '{print $1}'`
username=`echo $line | awk '{print $2}'`
passwd=`echo $line | awk '{print $3}'`
source=`echo $line | awk '{print $4}'`
target=`echo $line | awk '{print $5}'`
$dir/cpExeShell.sh $host $username $passwd $source $target
done < $dir/host.txt

最终确定

192.168.128.133 root /usr/local/shell/qianyan-dbs-2021-01-14-17-42-04592.war /usr/local/qianyan-testshi1.war
192.168.128.136 root /usr/local/shell/qianyan-dbs-2021-01-14-17-42-04592.war /usr/local/qianyan-testshi111.war
#!/usr/bin/expect -f
set HOST [lindex $argv 0]
set USERNAME [lindex $argv 1]
#set PASSWD [lindex $argv 2]
set source [lindex $argv 2]
set target [lindex $argv 3]
spawn scp  $source $USERNAME@$HOST:$target
expect eof
#expect eof 表示交互结束,退回到原用户
#!/bin/bash
dir=/usr/local/shell
while read line
do
host=`echo $line| awk '{print $1}'`
username=`echo $line | awk '{print $2}'`
#passwd=`echo $line | awk '{print $3}'`
source=`echo $line | awk '{print $3}'`
target=`echo $line | awk '{print $4}'`
$dir/cpExeShell.sh $host $username $source $target
if [ $? -eq 0 ]; then
    echo "succeed"
else
    echo "failed"
fi
done < $dir/host.txt

补充:

shell脚本中判断上一个命令是否执行成功

shell中使用符号“$?”来显示上一条命令执行的返回值,如果为0则代表执行成功,其他表示失败。

结合if-else语句实现判断上一个命令是否执行成功。

经过验证,该方法也适用于make命令,并不仅仅限于shell 命令。

if [ $? -eq 0 ]; then
    echo "succeed"
else
    echo "failed"
fi

shell中的比较符号如下:
-eq 等于
-ne 不等于
-gt 大于
-lt 小于
ge 大于等于
le 小于等于

linux expect详解

expect是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信。

expect自动交互流程:

spawn启动指定进程—expect获取指定关键字—send向指定程序发送指定字符—执行完成退出.

expect常用命令总结:

spawn               交互程序开始后面跟命令或者指定程序
expect              获取匹配信息匹配成功则执行expect后面的程序动作
send exp_send       用于发送指定的字符串信息
exp_continue        在expect中多次匹配就需要用到
send_user           用来打印输出 相当于shell中的echo
exit                退出expect脚本
eof                 expect执行结束 退出
set                 定义变量
puts                输出变量
set timeout         设置超时时间
interact        允许用户交互

你可能感兴趣的:(Linux学习,linux,shell)