Write by lyc at 2020-8-21

expect免交互脚本

安装

1
yum install expect -y

expect的常用命令

命令 说明
spawn 启动新的交互进程, 后面跟命令或者指定程序
expect 从进程中接收信息, 如果匹配成功, 就执行expect后的动作
send 向进程发送字符串
send exp_send 用于发送指定的字符串信息
exp_continue 在expect中多次匹配就需要用到
send_user 用来打印输出 相当于shell中的echo
interact 允许用户交互
exit 退出expect脚本
eof expect 执行结束, 退出
set 定义变量
puts 输出变量
set timeout 设置超时时间

1.spawn

  • spawn 命令是 expect 的初始命令,它用于启动一个进程,之后所有 expect 操作都在这个进程中进行;如果没有 spawn 语句,整个 expect 就无法执行了
  • spawn 命令后面,直接加上要启动的进程、命令等信息
1
spawn ssh root@192.168.100.100

2.expect

  • expect 首先要依附 spawn 命令下进程的输出结果,通过正则表达式匹配需要 send 的行,最后执行 expect 后面的动作或指令
  • 表达式或动作可以放两行,也可以使用{}的方式
1
2
3
4
5
6
7
8
# {} 大括号写法
spawn ssh -p52113 oldboy@192.168.56.8 /sbin/ifconfig eth0
expect "*password:" {send "123456\r"}

# 换行写法
spawn ssh -p52113 oldboy@192.168.56.8 /sbin/ifconfig eth0
expect "*password:"
send "123456\n"

3.exp_send 和 send

  • exp_send 命令是可以发送一些特殊符号,\r(回车), \n(换行), \t(制表符)等等。
  • send 只是发送普通的字符串

4.exp_continue

exp_continue 首先要处于一个 expect 命令中属于一个动作命令,作用是匹配第一个关键字以后,第二次匹配仍然从第一个关键字开始。多次yes/no的选择。

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/expect
spawn ssh -p22 root@192.168.1.179 /sbin/ifconfig eth0
set time out 60
expect {
-timeout 1
"yes/no" { exp_send "yes\r";exp_continue }
"*password:" {exp_send "123456\r"}
timeout { puts "expect was timeout by oudboy."; return }
}
expect eof
exit

5.send_user

send_user 命令用来把后面的参数输出到标准输出中去,而默认的 send, exp_send 命令都是讲参数输出到 spawn 的程序中去。

1
2
3
4
5
#!/usr/bin/expect
if { $argc != 3 } {
send_user "usage: expect scp-expect.exp file host dir\n"
exit
}

6.exit

exit 命令功能很简单,就是直接退出 exp脚本,但是你可以利用这个命令对脚本做些扫尾的工作。

1
2
3
4
exit -onexit {
exec rm $tmpfile
send_user "Good bye\n"
}

7.expect 变量

1
2
set 变量名 值   # 定义变量
puts $变量名 # 调用变量
1
2
3
4
5
# define var
set file [lindex $argv 0]
set host [lindex $argv 1]
set dir [lindex $argv 2]
set password "123456"

8.expect 关键字

expect 关键字一般用于 expect族命令中而不能在外面单独使用。

eof

eof 关键字用于匹配结束符

timeout

  • timeout 是一个全局性的时间控制开关,通过这个变量的赋值来规定整个expect操作时间,这个变量的服务是全局的,它不会纠缠于某一条命令。即使命令没有任何错误,到达这个时间程序就会停下来,激活下面 timeout 的动作。
  • timeout 为0表示立即超时,为-1表示永不超时
1
set time out 60
1
2
3
4
5
6
spawn ssh root@192.168.1.179
expect {
-timeout 60
-re "password:" {exp_send "word\r"}
timeout { puts "expect was timeout"; return }
}

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ cat expect_test1.exp
#!/usr/bin/expect
if { $argc != 3 } {
send_user "USAGE:expect expect_test1.exp file host dir\n"
exit
}

#define var
set file [lindex $argv 0]
set host [lindex $argv 1]
set dir [lindex $argv 2]
set password "123456"
#expect command
spawn scp -P52113 -p $file oldboy888@$host:$dir
expect {
"yes/no" {exp_send "yes\r",exp_continue}
"*password:" {exp_send "$password\r"}
}
expect eof
exit

create_ftp_user.exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ cat create_ftp_user.exp 
#!/usr/bin/expect
# define var
set ROOT_USER test1
set ROOT_PASSWORD 123456
set ROOT_PATH /data/test1
set ROOT_PID pure-ftpd
set ROOT_GID pure-ftpd

set timeout 60
spawn /usr/bin/pure-pw useradd ${ROOT_USER} -u ${ROOT_PID} -g ${ROOT_GID} -d ${ROOT_PATH} -m
expect {
"^Password" {send "${ROOT_PASSWORD}\r";exp_continue}
"*again" {send "${ROOT_PASSWORD}\r"}
}
expect eof

spawn /usr/bin/pure-pw mkdb
expect eof

exit