expect 基本语法
这是一个简单的expect脚本,代码如下:
#!/usr/bin/expect set timeout 30 spawn ssh -l username 123.56.71.70 expect "password:" send "php.hhsy.cc\r" interact
这里对常见的expect语法做一些解释:
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 使用交互性的命令,命令行传参数
例如:
#!/usr/bin/expect -f set username [lindex $argv 0] set password [lindex $argv 1] echo $username . $password expect eof
这里通过
set password [lindex $argv num]
从脚本外部传入参数。
expect一般用于实现用脚本来自动远程登录,对远程机器执行相关操作
测试机上的expect目录一般在/usr/bin/expect路径
下面是从网上查询的用法总结:
1. expect中的判断语句:
if { condition } { # do your things } elseif { # do your things } else { # do your things }
expect中没有小括号(),所有的if/else, while, for的条件全部使用大括号{}, 并且{ 与左边要有空格,否则会报错。另,else 不能单独占一行,否则会报错。
2. 字符串比较
if { "$node" == "apple" } { puts "apple" } elseif { "$node" == "other" } { puts "invalid name" exit 70 } else { puts "asd" }
对比string,使用==表示相等, !=标示不相等。
3. switch 语句
switch $location { "apple" { puts "apple" } "banana" { puts "banana" } default { puts "other" } }
记得左大括号{ 的左边要有空格,否则会报错
4. 读取用户输入
expect_user -re "(.*)\n" send_user "$expect_out(1, string)\n" expect_user -re 表示正则表达式匹配用户按下回车前输入的所有字符 expect_out(1, string) 表示第一个匹配的内容,即回车前所有字符 expect_out(buffer) 所有的buffer内容
5. break && continue
如c中一样,expect一样可以使用break && continue, 并且功能相同。注:只能用在循环中。
6. 定义交互命令
# stick control + z in variable set ControlZ \032 # stick control + c in variable set ControlC \x03 # define string embedded ctrl-z && tab set oddword foo\032bar\tgorp
7. { }大括号:保留所有字符原有的意思,而不做解释,类似于shell中的单引号
举例:set var {a$b[set c 3]\tddd} 将{}中的一坨东西直接赋值给var
8. {}的另外一个作用是可以续行,(其实是左大括号)
举例:
if {$count < 0} { break; }
而以下的写法则是错误的:
if {$count < 0} { break; }
9. []中括号:执行命令
举例:
set count [expr $count - 1 ] set a [set b 0]
10. ()小括号:expect中没有小括号。所有在C中用的小括号都要换成大括号
11. 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运行进程加个壳,用来传递交互指令。
12. expect "password:"
这里的expect也是expect的一个内部命令,有点晕吧,expect的shell命令和内部命令是一样的,但不是一个功能,习惯就好了。这个命 令的意思是判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则就等待一段时间后返回,这里等待时长就是前面设置的30秒
13. interact
执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上。如果你只是登录过去执行