Linux Expect 简介和使用实例

1 expect 简介

expect 是用来进行自动化控制和测试的工具。主要是和交互式软件telnet ftp passwd fsck rlogin ssh tip 等进行自动化的交互。对于大规模的linux 运维很有帮助。expect sourceforge

2 expect 基本使用

在linux运维和开发中,我们经常需要远程登录服务器进行操作,登录的过程是一个交互的过程,可能会需要输入yes/no password等信息。为了模拟这种输入,可以使用expect脚本。
expect是由tcl语言演变而来的,所以expect脚本的运行需要tcl的支持。安装tcl和expect的步骤请自行google。

2.1 expect 关键命令

send:向进程发送字符串,用于模拟用户的输入。注意一定要加\r回车
expect:从进程接收字符串
spawn:启动进程(由spawn启动的进程的输出可以被expect所捕获)
interact:用户交互
其中expect是关键的部分,expect英文有期待的意思,采用了tcl的模式-动作语法,此语法有以下几种模式:
单一分支语法:

expect "hello" {send "you said hello"}

当输出中包含hello后,输出you said hello
多分支模式语法:

expect {
      "lilei" {send "hello lilei"; exp_continue}
      "hanmeimei" {send "hello hanmeimei"; exp_continue}
      "how do you do ?" {send "how do you do ?"}
}

当输出中包含lilei时 输出hello lilei,同时循环此多分支语句
当输出中包含hanmeimei时 输出hello hanmeimei,同时循环此多分支语句
当输出中包含how do you do ?时 输出dow do you do

3 使用实例

3.1 远程登录服务器并创建文件夹
#!/usr/bin/expect 
set timeout -1
spawn ssh root@192.168.0.107
expect {
    "password" {send "123456\r";}
    "yes/no" {send "yes\r";exp_continue}
}
expect "root" {send "mkdir testExpect\r"}
expect eof
exit

3.2 expect脚本获取参数

expect.ex

#!/usr/bin/expect 
set ip [lindex $argv 0]
set password [lindex $argv 1]
set timeout -1
spawn ssh root@$ip
expect {
    "password" {send "$password\r";}
    "yes/no" {send "yes\r";exp_continue}
}
expect "root" {send "mkdir test1\r"}
expect "root" {send "mkdir test2\r"}
send "exit\r" //退出远程登录
expect eof
exit
./expect.ex 192.168.0.107 123456

3.3 远程登录服务器等待手动操作

expect.ex

#!/usr/bin/expect 
set ip [lindex $argv 0]
set password [lindex $argv 1]
set timeout -1
spawn ssh root@$ip
expect {
    "password" {send "$password\r";}
    "yes/no" {send "yes\r";exp_continue}
}
interact
./expect.ex 192.168.0.107 123456
3.4 使用scp传输文件
#!/usr/bin/expect 
set timeout -1
spawn scp test.txt root@192.168.0.107:/home/
expect {
    "password" {send "123456\r";}
    "yes/no" {send "yes\r";exp_continue}
}
expect eof
exit
3.5 在本地开启socks5的代理
 #!/usr/bin/expect 
 set timeout -1 //expect匹配输出的超时时间
 spawn ssh -N -D 0.0.0.0:1080 localhost //新建一个进程,执行ssh命令
 expect {
    "yes/no" {send "yes\r";exp_continue} //
    "password" {send "123\r"}
 }
 expect eof
 exit

4-5行是根据进程输出执行预先设置好的命令:
假如输出包含yes/no,则表示是第一次登入,需要输入yes来添加信任。exp_continue表示继续此循环。
假如输出包含password,表示需要输入密码。
8行的expect eof是在等待结束标志。由spawn启动的命令在结束时会产生一个eof标记,expect eof即在等待这个标记,因为ssh -N -D 0.0.0.107:1080 localhost 程序需要一直运行,所以将timeout 设置为-1即可无限制的等待。

3.6 指定登陆机器

从computerInfo里读取相应机器信息,用户选择登陆其中一台机器。
computerInfo:

#ip port user password description
192.168.1.1 root 123456 'first machine'
192.168.1.2 root 123456 'second machine'

core.ex

#!/usr/bin/expect 
set ip [lindex $argv 0]
set port [lindex $argv 1]
set username [lindex $argv 2]
set password [lindex $argv 3]
set timeout -1
spawn ssh -p $port $username@$ip
expect {
    "password" {send "$password\r";}
    "yes/no" {send "yes\r";exp_continue}
}
interact

login.sh

#!/bin/bash
file="computerInfo"
#显示机器信息 过滤第一行和空行
awk '{if (NR > 1 && $1 != ""){printf "%-2s %-45s %-15s \n",NR")",$5,$1}}' $file 
echo "please choose which machine to login:"
read number
#将信息存入变量
read ip port user password <<< $(echo `awk 'NR=="'$number'"{print $1,$2,$3,$4}' $file`)
./core.ex $ip $port $user $password
    原文作者:lvlvforever
    原文地址: https://www.jianshu.com/p/70556b1ce932
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞