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中使用符号“$?”来显示上一条命令执行的返回值,如果为0则代表执行成功,其他表示失败。
结合if-else语句实现判断上一个命令是否执行成功。
经过验证,该方法也适用于make命令,并不仅仅限于shell 命令。
if [ $? -eq 0 ]; then
echo "succeed"
else
echo "failed"
fi
shell中的比较符号如下:
-eq 等于
-ne 不等于
-gt 大于
-lt 小于
ge 大于等于
le 小于等于
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 允许用户交互