shell expect教程
一.介绍
shell功能很强大,但是不能实现有交互功能的多机器之前的操作,例如ssh和ftp.而expect可以帮助我们来实现.
二.安装expect
yum install expect
三.实例
1.登录到远程机器并停留
vim test.exp
#!/usr/bin/expect -f set ip [lindex $argv 0 ] //接收第一个参数,并设置IP set password [lindex $argv 1 ] //接收第二个参数,并设置密码 set timeout 10 //设置超时时间 spawn ssh root@$ip //发送ssh请滶 expect { //返回信息匹配 "*yes/no" { send "yes\r"; exp_continue} //第一次ssh连接会提示yes/no,继续 "*password:" { send "$password\r" } //出现密码提示,发送密码 } interact //交互模式,用户会停留在远程服务器上面.
使用:./test.exp 192.168.1.130 admin
2.登录到远程服务器,并且执行命令,执行完后并退出
#!/usr/bin/expect -f set ip 192.168.1.130 set password admin set timeout 10 spawn ssh root@$ip expect { "*yes/no" { send "yes\r"; exp_continue} "*password:" { send "$password\r" } } expect "#*" send "pwd\r" send "exit\r" expect eof
3.远程登录到ftp,并且下载文件
#!/usr/bin/expect -f set ip [lindex $argv 0 ] set dir [lindex $argv 1 ] set file [lindex $argv 2 ] set timeout 10 spawn ftp $ip expect "Name*" send "zwh\r" expect "Password:*" send "zwh\r" expect "ftp>*" send "lcd $dir\r" expect { "*file" { send_user "local $_dir No such file or directory";send "quit\r" } "*now*" { send "get $dir/$file $dir/$file\r"} } expect { "*Failed" { send_user "remote $file No such file";send "quit\r" } "*OK" { send_user "$file has been download\r";send "quit\r"} } expect eof
4.改装scp,使其不用密码
#!/usr/bin/expect -f #scp 远程copy文件 set user root set passwd zytech@e800 #接受传入的第一个参数 set file [lindex $argv 0] #接受传入的第二个参数 set ip [lindex $argv 1] set timeout 10//超时时间10秒 #spawn用来启动一个新的进程 spawn scp -r /home/zhu/softs/$file $user@192.168.8.$ip:/opt #expect用来等待你所期望的字符串,send用来发送字符串 expect { "*yes/no" { send "yes\r";exp_continue} "*password:" { send "$passwd\r" } } #行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。 #果没有这一句登录完成后会退出,而不是留在远程终端上。如果你只是登录过去执行一段命令就退出,可改为[expect eof] #interact expect eof
四.对于上述示例中相关命令的解释
1.[#!/usr/bin/expect]
这一行告诉操作系统脚本里的代码使用那一个shell来执行。这里的expect其实和linux下的bash、windows下的cmd是一类东西。
注意:这一行需要在脚本的第一行。
2.[set timeout 30]
基本上认识英文的都知道这是设置超时时间的,现在你只要记住他的计时单位是:秒
3.[spawn ssh -l username 192.168.1.1]
spawn是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。所以不要用 “which spawn“之类的命令去找spawn命令。好比windows里的dir就是一个内部命令,这个命令由shell自带,你无法找到一个dir.com 或 dir.exe 的可执行文件。
它主要的功能是给ssh运行进程加个壳,用来传递交互指令。
4.[expect “password:”]
这里的expect也是expect的一个内部命令,有点晕吧,expect的shell命令和内部命令是一样的,但不是一个功能,习惯就好了。这个命令的意思是判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则就等待一段时间后返回,这里等待时长就是前面设置的30秒
5.[send “ispass/r”]
这里就是执行交互动作,与手工输入密码的动作等效。
温馨提示: 命令字符串结尾别忘记加上 “/r”,如果出现异常等待的状态可以核查一下。
6.[interact]
执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上。如果你只是登录过去执行一段命令就退出,可改为[expect eof]
五.expect提供的常用命令使用参考
1.send
用来发送一个字符串,比如 send “hello world”。
初始情况下,这个字符串会发送到标准输出。如果你用的是max OSX或者linux,可以在Terminal下直接输入expect命令并回车,就进入了expect交互环境,此时,输入send “hello world”就可以看到结果。
一旦你的程序已经与其他程序进行交互,字符串就会被发送到其他程序那里。如上面的例子脚本中,我们调用send ”$password\r”就是把密码发送给SSH连接的服务器端指定端口。
2.expect
与send相反,expect用来等待你所期望的字符串。比如expect “hello”
在expect后面跟的字符串中,你可以指定一个正则表达式。
expect会一直等待下去,除非收到的字符串与预期的格式匹配,或者到了超期时间。
3.spawn
spawn用来启动一个新的进程,比如上面的spawn ssh -D $port $user@$host,Expect会执行命令“ssh -D $port $user@$host”。
在交互式的场景中,当你输入命令后,可能服务器端会返回一些操作提示符,以让你输入命令。Expect提供了这样三个常用的命令,spawn, expect和send,恰好满足这种需要。把它们结合起来使用,可以实现很多简单的自动化脚本。
其它常用的命令还有:interact,比如你通过脚本自动连接到了某个ftp,并输入了用户名密码,此时需要人工输入一些命令,就可以使用interact命令,它会把脚本的控制权交给用户;sleep,等待多少秒等等。
由于expect是从Tcl继承下来的,所以也支持Tcl的语法和命令,比如变量声明、流程控制等等。
上面脚本的一些解释:
1.set timeout 300:设置超时时间300s。如果设为-1,代表永不超时。
2.expect eof:等待接受文件结束符。
- 点赞
- 收藏
- 关注作者
评论(0)