linux下的自动交互工具expect

网友投稿 1314 2022-10-06

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

linux下的自动交互工具expect

描述

expect是一个根据脚本与其他交互式程序“对话”的工具,它可以根据从程序中预期的响应结果,并给回复自定义的命令来指导对话。此外,用户还可以在需要的时候直接控制当前交互窗口。

expect命令选项

选项说明
-c可执行命令的前置符,其后的命令应该被引起来,该选项可以使用多次,每个-c可以跟多个以分号分隔的命令。命令按照出现的顺序执行,例如:expect -c "puts first\n; puts second" -c "puts three"
-d输出一些诊断信息,命令执行时的内部动作。当你写的脚本和预期不符时,可用此项来调试脚本
-D交互式的调试器,类似gdb。适合专业人士使用
-f指定Expect读取的文件,如果文件是-,则表示是从标准输入读取。该选项会将文件一次性全部读入内存,该选项是可选的
-b类似-f选项,只是每次只读取一行
-i以交互的方式运行expect,等效直接敲expect
--可以用来界定选项的结束,此项可以用在当你想传递一个类似选项的参数时,防止Expect误认为是选项
-N/-n如果$exp_library/expect.rc和~/.expect.rc存在,Expect会分别自动读取,若要阻止此过程则需要分别指定-N和-n。此项一般用不上。
-v输出版本号并退出

核心命令 spawn、expect、send

  • spawn

    用于启动一个进程,通常都是expect脚本的第一步,默认情况下,spawn会回显命令名称和参数,可以用-noecho参数来让它不回显。

  • expect

    用于匹配,执行相应动作。匹配成功或超时或遇到文件尾时都会返回。一旦匹配上,则开始执行对应的语句。默认情况下,模式采用Tcl语言的string match命令匹配

      用法1: 
          expect 表达式 {动作} 表达式 {动作} ...   
      用法2
          expect {
              表达式 {动作}
              表达式 {动作}
              ...
          }

    模式中可用的特殊符号:

    符号-
    *匹配任何字符串,包括空null字符串
    ?匹配任意单个字符
    [chars]匹配chars中指定的字符集合,比如[A-Za-z]匹配所有字母,再比如[abc]匹配abc三个字符中的任意
    \x匹配字符x,提供了一种防止特殊字符转义的匹配方法,比如\可以匹配反斜杠这个字符,\?可以匹配问号,*可以匹配*
  • send

    用来发动作的,也可以使用exp_send命令(exp_send是send的别名)。支持八进制和十六进制发送,比如exp_send "\r" 可以写成 exp_send "\015"或exp_send "\x0d"

例子

一个ssh自动交互的例子,并总结了日常使用到的语法

#!/usr/bin/expect 
#shell通过expect解析本文件

#参数设定
set myip x.x.x.x
set myuser root
set mypwd 1234
set myport 22
puts "myinfo:ip:$myip user:$myuser pwd:$mypwd port:$myport"

#接收参数
set argv1 [lindex $argv 0]
puts argv1:$argv1

#关闭标准输出
log_user 0
#设置超时,-1为永久
set timeout 5
#spawn开始一个交互
spawn ssh $myuser@$myip -p $myport
#交互id
puts "spawnid:$spawn_id"
#执行shell命令并给变量,本地的shell
set centos [exec sh -c {cat /etc/centos-release}]
puts "centos:$centos"
set res [exec sh -c {hostname -i}]
puts "res:$res"
#进行匹配,exp_continue作用是从块的开始部分重新匹配表达式
expect {
       "*yes/no"   {send "yes\r";exp_continue}
       "*assword*" {send "$mypwd\r"}
       }

#睡眠2秒
sleep 2
#打开标准输出
log_user 1
expect "@" {send "echo source ip:$res\r"}
#log_user 0 #如果这时再关闭标准输出,则前面的打开会无效

#记录输出到日志文件
log_file a.log
set current_time [clock format [clock seconds] -format "%Y-%m-%d,%H:%M:%S"]
expect "@" {send "echo current_time:$current_time\r"}
#log_file #关闭日志文件,前面记录的都会没有
#打开文件进行写入
set myfile [ open telnetoutput w ]
#往文件$myfile写入内容$current_tim
puts $myfile $current_time;

#if条件
if { "$argv1" == "interact" } {
"interact"
else {
puts "no interact"
}


puts "please input:"
#匹配用户的输入
expect_user {
        -re {[cC]hina} { puts stdout "中国" }
        -re {[jJ]apan} { puts stderr "日本" }
    }

#发送ctrl+c
#send "\003"
#把交互窗口的操作交给用户
#interact
expect "@" {send "exit\r"}
#eof结束
expect eof

运行结果

[root@yejf]~/yejf# ./test.exp
myinfo:ip:x.x.x.x user:root pwd:1234 port:22
argv1:
spawnid:exp6
centos:CentOS Linux release 7.5.1804 (Core)
res:192.168.43.100

Last login: Tue May 26 17:04:17 2020 from x.x.x.x
[root@mas01 ~]$ please input:
china
中国
echo source ip:192.168.43.100
source ip:192.168.43.100
[root@mas01 ~]$ echo current_time:2020-05-26,17:06:20
current_time:2020-05-26,17:06:20
[root@mas01 ~]$ hostname -i
x.x.x.x
[root@mas01 ~]$ exit
登出

日志文件

[root@yejf]~/yejf# cat a.log
china
echo source ip:192.168.43.100
source ip:192.168.43.100
[root@mas01 ~]$ echo current_time:2020-05-26,17:06:20
current_time:2020-05-26,17:06:20
[root@mas01 ~]$ hostname -i
x.x.x.x
[root@mas01 ~]$ exit
登出

写入的文件

[root@yejf]~/yejf# cat telnetoutput
2020-05-26,17:06:20

scp自动交互的例子

expect <<EOF
    set timeout 10
    spawn scp $file $username@$ip:/tmp
    expect {
        "yes/no" { send "yes\n";exp_continue }
        "*assword" { send "$userpwd\n" }
    }
    expect "100%" {puts "SUCCEED:scp file:$file\r"}
    expect eof
EOF


上一篇:Linux 网卡 bonding 小知识
下一篇:零数据丢失恢复一体机(ZDLRA)架构基础与运维介绍
相关文章

 发表评论

暂时没有评论,来抢沙发吧~