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
\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:
- interact 和 expect eof 的区别
expect eof 表示交互结束,退回到原用户;expect脚本默认的是等待10s,
interact 会停留在目标用户
expect 案例
- 自动登录 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 # 交互模式,用户会停留在远程服务器上面
- 自动 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
- 自动建立 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
- 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]#