shell中 expect 命令

expect 自动交互脚本

expect 常用选项

  • expect :期望、期待、预期
-c:  执行脚本前先执行的命令,可多次使用。
-d:  debug模式,可以在运行时输出一些诊断信息,与在脚本开始处使用exp_internal 1相似。
-D:  启用交换调式器,可设一整数参数。
-f:  从文件读取命令,仅用于使用#!时。如果文件名为"-",则从stdin读取(使用"./-"从文件名为-的文件读取)。
-i:  交互式输入命令,使用"exit"或"EOF"退出输入状态。
--:  标示选项结束(如果你需要传递与expect选项相似的参数给脚本时),可放到#!行:#!/usr/bin/expect --。
-v:  显示expect版本信息

expect 常用命令

# 命令行参数 
# $argv,参数数组,使用[lindex $argv n]获取,$argv 0为脚本名字
# $argc,参数个数
set username [lindex $argv 1]  # 获取第1个参数
set passwd [lindex $argv 2]    # 获取第2个参数

set timeout 30 # 设置超时

# spawn是expect内部命令,开启ssh连接
spawn ssh -l username 192.168.1.1

# 判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则就等待一段时间(timeout)后返回
expect "password:"

# 发送内容ispass(密码、命令等)
send "ispass\r"

# 发送内容给用户
send_user "$argv0 [lrange $argv 0 2]\n"
send_user "It's OK\r"
# 执行完成后保持交互状态,控制权交给控制台(手工操作)。否则会完成后会退出。
interact
  • "\n""\r" 的区别
\r:回车,      r->return
\n:换行,    n->newline

Linux中 \n 表示回车+换行;\r 表示回车、确认(例如:输入密码后回车确认)

expect 命令介绍

close:关闭当前进程的连接。
debug:控制调试器。
disconnect:断开进程连接(进程仍在后台运行)。
定时读取密码、执行priv_prog
exit:退出expect。
exp_continue [-continue_timer]:继续执行下面的匹配。
exp_internal [-f file] value:
  • interactexpect eof 的区别
expect eof 表示交互结束,退回到原用户;expect脚本默认的是等待10s,

interact 会停留在目标用户

expect 案例

  1. 自动登录 ssh
#!/usr/bin/expect -f  
set ip [lindex $argv 0 ]         # 接收第1个参数,作为IP
set username [lindex $argv 1 ]   # 接收第2个参数,作为username
set mypassword [lindex $argv 2 ] # 接收第3个参数,作为密码
set timeout 10                   # 设置超时时间 

spawn ssh $username@$ip       # 发送ssh请求
expect {                      # 返回信息匹配 
"*yes/no" { send "yes\r"; exp_continue}  # 第一次ssh连接会提示yes/no,继续  
"*password:" { send "$mypassword\r" }    # 出现密码提示,发送密码  
} 
interact        # 交互模式,用户会停留在远程服务器上面
  1. 自动 telnet 会话
#!/usr/bin/expect -f
set ip [lindex $argv 0 ]         # 接收第1个参数,作为IP
set userid [lindex $argv 1 ]     # 接收第2个参数,作为userid
set mypassword [lindex $argv 2 ] # 接收第3个参数,作为密码
set mycommand [lindex $argv 3 ]  # 接收第4个参数,作为命令
set timeout 10                   # 设置超时时间

    # 向远程服务器请求打开一个telnet会话,并等待服务器询问用户名
    spawn telnet $ip
    expect "username:"
    # 输入用户名,并等待服务器询问密码
    send "$userid\r"
    expect "password:"
    # 输入密码,并等待键入需要运行的命令
    send "$mypassword\r"
    expect "%"
    # 输入预先定好的密码,等待运行结果
    send "$mycommand\r"
    expect "%"
    # 将运行结果存入到变量中,显示出来或者写到磁盘中
    set results $expect_out(buffer)
    # 退出telnet会话,等待服务器的退出提示EOF
    send "exit\r"
    expect eof
  1. 自动建立 FTP 会话
# 向远程服务器请求打开一个FTP会话,并等待服务器询问用户名
 spawn ftp $remote_server
 expect "username:"

 # 输入用户名,并等待服务器询问密码
 send "$my_user_id\r"
 expect "password:"

 # 输入密码,并等待FTP提示符的出现
 send "$my_password\r"
 expect "ftp>"

 # 切换到二进制模式,并等待FTP提示符的出现
 send "bin\r"
 expect "ftp>"

 # 关闭ftp的提示符
 send "prompt\r"
 expect "ftp>"

 # 下载所有文件
 send "mget *\r"
 expect "ftp>"

 # 退出此次ftp会话,并等待服务器的退出提示EOF
 send "bye\r"
 expect eof
  1. ssh 登陆后执行命令
#!/usr/bin/expect
spawn ssh root@192.168.121.11

expect {
	"yes/no" { send "yes\n";exp_continue }
	"password" {send "root\n"}
}
expect "#" {send "ls\n"}
expect "#" {send "pwd\n"}
send "df -h\n"
send "ls /home\n"
expect eof
  • 执行结果
[root@192 script]# ./ssh.sh 
spawn ssh root@192.168.121.11
Last login: Wed Dec 30 11:53:15 2020 from 192.168.121.17
[root@192 ~]# ls
anaconda-ks.cfg
[root@192 ~]# pwd
/root
[root@192 ~]# df -h
Filesystem             Size  Used Avail Use% Mounted on
devtmpfs               887M     0  887M   0% /dev
tmpfs                  904M     0  904M   0% /dev/shm
tmpfs                  904M  8.6M  895M   1% /run
tmpfs                  904M     0  904M   0% /sys/fs/cgroup
/dev/mapper/rhel-root   50G  1.8G   49G   4% /
/dev/mapper/rhel-home   27G  225M   27G   1% /home
/dev/nvme0n1p1        1014M  173M  842M  17% /boot
tmpfs                  181M     0  181M   0% /run/user/0
[root@192 ~]# ls /home
[root@192 ~]# [root@192 script]# 
posted @ 2020-12-29 16:11  廿九九  阅读(2222)  评论(0)    收藏  举报