有时我们想使用shell脚本做一些自动操作,例如ssh或scp时自动输入密码,可以使用expect工具来实现。
需求:
使用shell与expect混合编程,将一个文件从机器A(Ubuntu16.04)中的目录mydata打包为mydata.tar.gz自动scp到机器B中(Ubuntu18.04),能自动接受yes/no询问,能自动输入密码。
按照网上的操作遇到的问题:
脚本自动跑了,但在自动输入密码时直接跳过了,导致自动scp失败
最终成功的脚本:
#!/bin/bash
SCRIPT_HOME=$(cd "$(dirname "$0")"; pwd)
cd $SCRIPT_HOME
tar cvf mydata.tar.gz mydata/
expect <(cat << 'MYEOF'
set timeout 5
spawn scp mydata.tar.gz keycer@192.168.0.139:/home/keycer
expect {
"*(yes/no)?" {send "yes\r"; exp_continue}
"*password:" {send "keycer\r"; exp_continue}
}
#下面不能使用interact和expect eof, 具体原因请查看https://blog.csdn.net/modi000/article/details/107115286/
#经测试使用了interact会报错:spawn_id: spawn id exp4 not open
#interact
MYEOF
)
脚本截图(为防止上面代码编辑器对某些空格的错误处理):
注意事项:
(1)spawn,send,interact 命令是expect工具中自带的命令,在shell中无法运行,必须要在expect环境中才能正常使用
(2)注意使用的是bash脚本引擎,经测试使用dash脚本引擎运行会报错
(3)第一行SCRIPT_HOME=那是在获取脚本所在的目录
(4)脚本在Ubuntu16.04环境中运行成功
参考链接:
(1)expect脚本中使用expect eof 和使用interact的区别:https://blog.csdn.net/modi000/article/details/107115286/
(2)Shell脚本与expect脚本混合编程的正确方法:https://stackoverflow.com/questions/41165719/embedding-an-expect-script-inside-a-bash-script