1. 介绍

expect是建立在tcl(参见:Tcl/Tk快速入门 )基础上的一个工具,它可以让一些需要交互的任务自动化地完成。相当于模拟了用户和命令行的交互操作。 
一个具体的场景:远程登陆服务器,并执行命令 
登录时输入密码需要交互,bash脚本无法完成,可以使用expect来完成。

2. 安装

下面介绍两种安装方式

yum 安装

yum install -y expect
  • 1
  • 2

源码编译安装

expect 依赖于 tcl, 所以需要首先安装 tcl。可以使用rpm检查是否已经安装tcl:

rpm -qa | grep tcl
  • 1
  • 2

如果已安装,则会打印出tcl软件信息

安装过程参考:linux expect 安装 http://www.cnblogs.com/daojian/archive/2012/10/10/2718390.html 
tcl 地址:https://sourceforge.net/projects/tcl/files/Tcl/ 选择一个版本 
expect 地址:https://sourceforge.net/projects/expect/files/Expect/ 选择一个版本 
注意:wget 下载的时候需要加上 –no-check-certificate, 不检查网站证书

3. 原理与工作机制

首先使用 spawn 开启一个会话,然后使用 expect-send 对来执行交互式操作。 
spawn 后面跟上一个命令操作,表示开启一个会话。expect 等待输出特定的字符串(通常是提示符),然后使用send 发送交互字符串。比如:

spawn ssh username@host # 远程登录

expect "*assword" # 提示为:"username@host's password:", 等待用户输入密码
send "${password}\r" # 这时使用send模拟用户输入密码的字符串,完成登录验证
  • 1
  • 2
  • 3
  • 4
  • 5

4. 基本语法介绍

脚本解释器

脚本中首先引入文件,表明使用的是哪一个shell

#!/usr/bin/expect
  • 1
  • 2

set

设置会话超时时间为30s, 若不限制超时时间则应设置为-1

set timeout 30
  • 1
  • 2

set 还可以设置变量

# 使用变量语句:$param 或者 ${param}({}用来避免param和后面的字符串拼接起来导致错误)
set param "param_str"
set param 1
  • 1
  • 2
  • 3
  • 4

spawn

spawn 后面跟一个命令,开启一个会话

spawn ${cmd} # for example : spawn su root
  • 1
  • 2

expect - send

expect 接收命令执行后的输出,然后和期望字符串匹配,若对应这执行相应的send来发送交互信息。

expect "$case1" {send "$respond1\r"} # 这一行等同于下面两行

expect "$case1"
send "$response1\r"
  • 1
  • 2
  • 3
  • 4
  • 5

expect 可以有多个分支,就像switch语句一样。

expect
{
"$case1" {send "$response1\r"}
"$case2" {send "$response2\r"}
"$case3" {send "$response3\r"}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

结束符

expect eof :等待执行结束,若没有这一句,可能导致命令还没执行,脚本就结束了 
interact : 执行完成后保持交互状态, 这时可以手动输入信息 
注:expect eof 与 interact 二选一即可

接收参数

参数存在argv中,使用第一个参数如下:

set param0 [lindex $argv 0]
  • 1
  • 2

$argc表示参数个数,判断语句如下:

if {$argc < 1} {
#do something
send_user "usage: $argv0 <param1> <param2> ... "
exit
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注:$argv0 是脚本名,但[lindex $argv 0]是第一个参数 param1, [lindex $argv 1]是第二个参数 param2, 以此类推 
send_user 用来显示信息到父进程(一般为用户的shell)的标准输出。

5. 实例

实现远程登录服务器,并切换到root用户下执行关闭防火墙的命令,然后退出

#!/usr/bin/expect

if {$argc < 4} {
#do something
send_user "usage: $argv0 <remote_user> <remote_host> <remote_pwd> <remote_root_pwd>"
exit
} set timeout -1
set remote_user [lindex $argv 0] # 远程服务器用户名
set remote_host [lindex $argv 1] # 远程服务器域名
set remote_pwd [lindex $argv 2] # 远程服务器密码
set remote_root_pwd [lindex $argv 3] # 远程服务器根用户密码 # 远程登录
spawn ssh ${remote_user}@${remote_host}
expect "*assword:" {send "${remote_pwd}\r"}
expect "Last login:" # 切换到 root
send "su\r"
expect "*assword:" {send "${remote_root_pwd}\r"} # 执行关闭防火墙命令
send "service iptables stop\r"
send "exit\r"
send "exit\r"
expect eof

将代码保存到 remot_root_command.exp 中,权限改为755,然后执行下面这条命令即可:

./remote_root_command.exp <remote_user> <remote_host> <remote_pwd> <remote_root_pwd>

每次进步一点点——linux expect 使用的更多相关文章

  1. [转载]expect spawn、linux expect 用法小记

    原文地址:expect spawn.linux expect 用法小记作者:悟世 使用expect实现自动登录的脚本,网上有很多,可是都没有一个明白的说明,初学者一般都是照抄.收藏.可是为什么要这么写 ...

  2. Linux expect用法介绍

    1.expect是linux中一个交互命令,一般在 /usr/bin/expect路径下,如果该路径未加入到环境中需要先添加,其作用场景常用于交互执行输入指令 常用命令: expect 获取上一命令执 ...

  3. linux expect, spawn用法小记

    linux expect, spawn用法小记_IT民工_百度空间 linux expect, spawn用法小记 版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明http://sys ...

  4. 一点点linux系统的学习心得

    我相信你正在阅读本文的时候,可能是因为你渴望学习Linux技术.我想分享一下过去两年中我自己的一些学习经历,希望你能更顺利地成为Linuxer. 两年前在Linux系统的运行和维护方面找到了一份工作( ...

  5. Linux expect 使用(免密登录跳板机)

    登录公司的跳板机是挺麻烦的事,首先要ssh,然后输入密码,有的公司可能还要动态密码,前两步操作都是固定的,所以能免去前两步的操作就会方便很多(线上出问题也能尽快登上去,免得紧张密码一直输错,哈哈哈). ...

  6. Linux expect详解

    随处可见的expect第一次见expect这个命令还是我第一次参加全量上线的时候,那是公司的一个牛人用Shell脚本写的一套自动部署.MD5 比对.发布的全量上线工具,没事的时候,看了下其中的几个脚本 ...

  7. linux expect 简单讲解

    来自http://blog.csdn.net/winstary/archive/2009/08/08/4422156.aspx使用expect实现自动登录的脚本,网上有很多,可是都没有一个明白的说明, ...

  8. expect spawn、linux expect 用法小记

    使用expect实现自动登录的脚本,网上有很多,可是都没有一个明白的说明,初学者一般都是照抄.收藏.可是为什么要这么写却不知其然.本文用一个最短的例子说明脚本的原理. 脚本代码如下: ######## ...

  9. Linux expect自动登录ssh,ftp

    [http://blog.51yip.com/linux/1462.html#] #!/usr/bin/expect -f set ip 192.168.1.201 set password meim ...

随机推荐

  1. Codeforces Round #575 (Div. 3) C. Robot Breakout (模拟,实现)

    C. Robot Breakout time limit per test3 seconds memory limit per test256 megabytes inputstandard inpu ...

  2. Vue基础第三章 - 计算属性

    1.计算属性介绍 在第二章中我们介绍了在Vue的{{}}中可以使用一些简单的表达式进行计算,但是当表达式过长或者逻辑过于复杂就会变得不易理解和维护,比如第二章的示例{{ text.split(',') ...

  3. java课堂作业3 第一题 能查阅申请对象个数

    实验代码 public class Num { public static void main(String[] args) { // TODO Auto-generated method stub ...

  4. python 脚本制作

    U盘拷贝 当U盘插入主机时 被系统识别挂载后 通过python代码自动的去读取U盘中的资料并且进行拷贝 寄存在U盘上的 把硬盘上的资料进行读取并移动到U盘里 有点像 繁殖性 传输性 破坏性 破坏系统或 ...

  5. The Preliminary Contest for ICPC Asia Shanghai 2019 J. Stone game

    题目:https://nanti.jisuanke.com/t/41420 思路:当a(a∈S′)为最小值 如果Sum(S′)−a≤Sum(S−S′)成立 那么(∀t∈S′,Sum(S′)−t≤Sum ...

  6. Linux下lazarus交叉编译 win32[win64]

    环境 vmvare + deepin Linux64 + lazarus2.0.6 参考:https://wiki.freepascal.org/Cross_compiling_for_Win32_u ...

  7. [人物存档]【AI少女】【捏脸数据】两个人物

    点击下载(城通网盘):8bcd58f40ad162d9c1fd6f641edfa9ec8b13cdf8.png 点击下载(城通网盘):AISChaF_20191110015122738.png

  8. C# 获得对象的命名空间 ?.

    A a = new A(); var t = a?.ToString(); //t = WebApplication1.Controllers.A //获得命名空间和类名 var t1 = (A)nu ...

  9. CF718C Sasha and Array 线段树 + 矩阵乘法

    有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$   直接求不好求,改成矩阵乘法的形式:  $a_{i}=M^x\times ...

  10. hdu 1754 线段树 水题 单点更新 区间查询

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...