浅谈linux基础之expect交互
扫描二维码
随时随地手机看文章
某些情况下需要自动输入密码,您可以用expect。
自动与交互式程序会话。
脚本
#!/usr/bin/expect -f
argv:接收参数
argc:参数个数
argv0:脚本名
选项
-c "cmd":指定在执行脚本之前执行的命令,这些命令最好用双引号括起,防止被shell分开解释,可以反复使用-c
-d:输出调试信息,报告expect和interact等命令执行时的内部行为,脚本开头写"exp_internal 1"也可以达到同样的效果
-D:交互式调试器
-f:指定命令文件
-i:交互式提示输入命令
--:划定选项尾,如脚本中写 #! /usr/bin/expect - ,则任何命令行的选项都会被解释为参数,被argv接收
命令
setfile “xxx” 设置参数file的值为"xxx"
close:关闭与当前进程的链接
expect和interact都可以检查到进程的退出,隐含执行一个close命令,如果用exec kill pid方式杀进程,则需要显示调用一次close指令
-slave 同时关闭从属进程
-onexec 0 保持spawn_id 开启,1关闭当前的spawn_id
-i 指定关闭的spawn_id
debug:调试
now立即启动调试器,0停止,1启动
disconnect:从终端断开与克隆进程的连接,克隆进程会在后台作为独立进程组继续运行,IO被重定向到/dev/null
send_user "password?\ "
expect_user -re "(.*)\n"
for {} 1 {} {
if [fork]!=0 {sleep 3600;continue}
disconnect #克隆进程继续运行
spawn priv_prog
expect Password:
send "$expect_out(1,string)\r"
. . .
exit
}
Exp_continue[-continue_timer]
这个命令可以使expect继续执行而不是正常的返回.默认情况下,exp_continue会重高超时时钟,-continue_timer选项会阻止时钟重新计数(连续计数).
Exp_internal [-f file] value
如果是value非零的话,使接下来的命令将调试信息输出到Expect和标准错误输出.如果是0的话,输出的信息将会被屏蔽.调试信息包括收到的每条信息和每次尝试用当前输出与脚本中的模式相匹配的信息.如果设置了输出文件,那么正常的和调试的信息都会被写到这个文件当中.(忽略上面value选项的值).任何之前打开的调试输出文件将会被关闭.-info选项使exp_internal返回最近关于non-info参数的描述
Exp_open [args] [-I spawn_id]
它返回对应于原始spawn id的文件描述符.这样这个文件描述符就可以被使用了,就好像这个文件是被Tcl的open指令打开的一样.(这个spawn id将不再使用,wait指令将不能用在这个进程.).-leaveopen选项使spawn id保持打开,以便供Expect命令使用
Exp_pid [-i spawn_id]
它将返回对应于当前被跟踪进程的ID.如果使用-i选项,将返回对应于指定的spawn id的进程ID.
Exp_send:send别名
Exp_send_error:它是Send_error
Exp_send_log:Send_log
Exp_send_tty:Send_tty
Exp_send_user:Send_user
Exp_version [[-exit] version]
它用于确保脚本程序与当前的Expect兼容。在没有参数的情况下,返回当前Expect的版本.这个版本就会编译到脚本中.如果你确切的知道你的脚本程序不需要最新版本的特性,可以指定一个以前的版本
expect_tty [expect_args ],输入是一个tty
expect_user [expect_args],输入是stdin
expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]
等待被监控进程的输出,如果匹配到指定输出字符串、遇到文件尾、或超时时,则执行对应的body体,如果body是空的,将被忽略
-nocase 匹配时不区分大小写
-timeout:选项使得Expect使用选项后面的数值做为超时时间,而不是timeout变量中设置的时间
expect_befor模式,在所有匹配之前隐含调用
expect_after模式,在所有匹配之后隐含调用
expect {
busy {puts busy\n ; exp_continue} # 输出值有busy执行{}里面的语句
failed abort # 输出有failed,执行abort,abort是预定义的一个函数
"invalid password" abort #输出字符串中间有空格,需要用双引号括起来
-re "failed|invalid password" abort #使用正则表达式
-ex "failed|invalid *password" abort #精准正则,不对* ^等转义
-i $proc2 busy {puts busy\n ; exp_continue} #匹配$proc2进程的输出,默认是当前进程的输出
-i $proc3 # 匹配到执行XXX
-i $proc4 # 匹配到执行XXX
any_spawn_id XXX
timeout abort #超时时触发
full_buffer abort #输出的值超过最大的match_max设置的值是触发
null #输出ascii 0时触发
connected
}
匹配时,任何输出都会被保存到expect_out缓冲区中,匹配到的9个字串分别被保存在expect_out(1, string) ~ expect_out(9, string),如果在模式前面使用了 -indeces 选项,则这9个字串的起始位置和结束位置保存在expect_out(X, start)和expect(X, end)中,X∈[0, 9]。expect(0,*)是匹配到的整个字符串,下面三条语句等效
expect "cd"
Set expect_out(0,string) cd
Set expect_out(buffer) abcd
-i选项还可以定义一个全局变量,里面存储着spawn_id列.当变量内容发生变化时,它会被重新读取.这样就可以在程序执行的时候改变I/O源.以这种方式提供的spawn_id被称为”indirect spawn_id”
Fork
复制一个进程,返回新进程ID,失败返回-1
interact [string1 body1] ... [stringn [bodyn]]
将控制权给用户,根据用户的输入,触发相应的动作
set CTRLZ \032
interact {
-reset $CTRLZ {exec kill -STOP [pid]} # 按下ctrl+z触发
\001 {send_user "you typed a control-A\n"; # 发送一个字符串到终端
send "\001"
}
$ {send_user "The date is [exec date]."}
\003 exit
foo {send_user "bar"} # 用户输入foo时触发
~~
}
send:发送字符串给当前进程
send_user:发送字符串到标准输出
send_error:发送字符串到标准错误
send_log:发送字符串到日志文件
send_tty:发送字符串到tty
sleep seconds:休眠
spawn [args] program [args]
创建一个执行program命令的进程,这个进程的三个标准IO都被重定向到expect,
spawn su - ftomcat -c "tar -xzf /tmp/ftomcat.tgz . 1>/dev/null 2>/dev/null"
expect "Password"
send "ftomcat\r"
expect eof
exit