expect用于自动化地执行linux环境下的命令行交互任务,例如scp、ssh之类需要用户手动输入密码然后确认的任务。有了这个工具,定义在scp过程中可能遇到的情况,然后编写相应的处理语句,就可以自动地完成scp操作了。使用expect工具需要先行进行安装,可以使用apt-get或pacman这些包管理工具去获取安装,或者到expect开源项目的网站:http://expect.sourceforge.net/ 来获取。
【expect|expect登陆远程主机进行无交互操作】expect中最关键的四个命令:
send:用于向进程发送字符串命令
expect:从进程接收字符串
spawn:启动新的进程
interact:允许用户交互,执行完操作之后留在远程服务器上。
1.expect执行ssh登录远程主机
#!/usr/bin/expect# 指明expect的执行路径set user [lindex $argv 0]
set passwd [lindex $argv 1]
set hostip [lindex $argv 2]spawn ssh $user@$hostip#ssh登录主机
expect {
"yes/no" {send "yes\r";
exp_continue}#匹配是否有提示yes/no,如果有,发送yes,exp_continue表示如果前面的条件没有被匹配,继续执行下一步。
"*paasword" {send "$passwd\r"}#回显出现paasword让输入密码。直接发送密码登录
}set timeout -1# 设置超时时间,-1表示无穷大expect "*#"#判断用户,是否是root,有些操作只有root才有权限
send "mkdir -r /home/test\r"#创建 /home/test目录expect eofinteract#执行完上述操作,如果需要手动执行,可以停留在远程主机,不会退出。否则,执行完毕之后,自动退出
2.shell脚本调用expect
我们可以单独的将expect的部分写作一个脚本,在shell中直接执行 expect 脚本名调用,但有时候我们只需要简单的修改一部分shell,没必要去单独的引用一个脚本,这就需要我们在shell脚本中进行嵌套调用
1> 使用expect -c嵌套调用
#!/usr/bin/bashset user=$argv0
set passwd=$argv1
set hostip=$argv2echo "welcome to ssh $hostip"# expect -c "" 内所有的双引号都需要有 \ 转义符号
expect -c "
spawn ssh $user@$hostip#ssh登录主机
expect {
\"yes/no\" {send \"yes\r\";
exp_continue}#匹配是否有提示yes/no,如果有,发送yes,
exp_continue表示如果前面的条件没有被匹配,继续执行下一步。
\"*paasword\" {send \"$passwd\r\"}#回显出现paasword让输入密码。直接发送密码登录
}set timeout -1# 设置超时时间,-1表示无穷大expect \"*#\"#判断用户,是否是root,有些操作只有root才有权限
send \"mkdir -r /home/test\r\"#创建 /home/test目录expect eofinteract#执行完上述操作,如果需要手动执行,可以停留在远程主机,不会退出。否则,执行完毕之后,自动退出"
echo "byebye"
2>.Document文本嵌套
#!/usr/bin/bash# 指明expect的执行路径set user=$argv1
set passwd=$argv2
set hostip=$argv3echo "welcome to ssh@$hostip"/usr/bin/expect <
3.获取expect远程主机上执行脚本的返回值
获取返回值,只需要在expect脚本末尾加上
catch wait result;
exit [lindex \$result 3]
如果我们在远程主机上执行了一个脚本,如何判断远程主机上的脚本是否执行成功呢?最常见的方式就是判断脚本执行完的退出码是否为0
如果采用这种方式的话,不管脚本是否能执行成功,退出码永远是0
#!/usr/bin/bash# 指明expect的执行路径set user=$argv1
set passwd=$argv2
set hostip=$argv3echo "welcome to ssh@$hostip"/usr/bin/expect <
但是如果脚本命令直接跟在spawn ssh之后的话,就可以获取到脚本的退出码. -q 是登录到远程主机之后执行的命令,只能执行一条语句。双引号之内,可以使用"; "隔开,执行多个语句。
#!/usr/bin/bash# 指明expect的执行路径set user=$argv1
set passwd=$argv2
set hostip=$argv3echo "welcome to ssh@$hostip"/usr/bin/expect <
推荐阅读
- Linux|Shell 编程~人入门到入坑。
- Linux技术|Windows平台下ADB的安装与使用
- c#|C#中使用SHFileOperation调用Windows的复制文件对话框
- Shell|Linux下 svn命令操作
- ubuntu环境|ubuntu10.04 常用命令
- ubuntu环境|Linux SSH相关命令
- python|合并和排序 Linux 上的文件 | Linux 中国
- 脚本输入处理——选项处理
- Shell|Shell脚本学习总结
- Shell|Linux: grep命令多关键字的“与”和“或”