1. 说明

  在编写脚本时,可能会遇到需要在另一台主机上执行一个命令,或者在本机拷贝另一台主机内的一个文件。如果两台主机之间没有做互信,就会牵扯到用户输入密码的交互过程,这对编写自动脚本来说, 就行不通了。

要实现在脚本内的自动交互,就需要 expect

2.  expect 命令介绍

  expect 是一个用来处理交互的命令。借助 expect 可以将交互过程写在一个脚本里,就可以实现自动化完成。上面的问题也能得到解决。

形象来说,如下命令的交互都能得到解决:

  1. ssh
  2. scp
  3. ftp

CentOS / RHEL 安装 expect

# yum install expect -y

2.1 expect 中常用的命令

  expect 中最关键的四个命令: send 、 expect 、spawn 、 interact

  • send:用于向进程发送字符串
  • expect:从进程接收字符串
  • spawn:启动新的进程
  • interact:允许用户交互

(1) send 命令

  send命令接收一个字符串参数,并将该参数发送到进程。

[root@localhost ~]# expect
expect1.1> send "hello china\n"
hello china

(2) expect命令

A. 基础知识

  expect命令和send命令正好相反,expect通常是用来等待一个进程的反馈。expect可以接收一个字符串参数,也可以接收正则表达式参数。和上文中的send命令结合。

#!/usr/bin/expect
expect "hi\n"
send "hello there!\n"

上面脚本的意思:

expect "hi\n"  --> 从标准输入中等待 "hi\n"

send "hello there!\n" --> 向标准输出输出 hello where

如果写成简单的伪代码如下:

if [ "$cmd" == "hi" ] ; then
echo "hello there!"
fi

来看一个简单的 expect 脚本:

#!/usr/bin/expect
expect "hi\n"
send "you typed <$expect_out(buffer)>"
send "but I only expected <$expect_out(0,string)>"

执行结果:

通过执行脚本,可以判定:

  $expect_out(buffer)   匹配到的是所有输入

  $expect_out(0,string)   匹配到 expect 参数的输入 

B. 模式 - 动作

(a)单一分支模式语法:

expect "hi" {send "You said hi\n"}

只有当输入 hi 时, 才会返回  "You said hi\n"

(b)多分支模式语法:

expect "hi" { send "You said hi\n" } \
"hello" { send "Hello yourself\n" } \
"bye" { send "That was unexpected\n" }

匹配到 hi 、hello 、 bye 执行相应的输出:

hi --> You said hi\n
hello --> You said hi\n
bye --> That was unexpected\n

(3) spawn 命令

上面的测试都是通过手动输入来进行交互的,spawn 命令就是用来启动新的进程,然后通过 send 和 expect 和 spawn 打开的进程进行交互的。

#!/usr/bin/expect
set timeout -1
spawn scp root@192.168.118.15:/root/testfile /root/
expect "*password*"
send "123456\r"
expect "100%"
expect eof

执行结果:

通过 spawn 配合 expect 、send 就能实现自动交互了,接下来分析下这个代码:

(4)interact 命令

  通过上面三个命令 spawn 、 send 、 expect 已经能完成很多自动化脚本了,但是,如果需要在适当的时候,需要人工干预这个过程,就需要用到 interact 命令。

#!/usr/bin/expect
set timeout -1
spawn ssh root@192.168.118.15
expect "*password*"
send "123456\r"
expect "#*"
send "ip a | egrep global\r"
interact

3. expect 使用实例

  expect 经常是作为脚本出来的, 接下来通过我日常使用的几个实例来说明:

3.1 expect scp的实现

  scp 执行流程如图:

        

在编写实现 scp 之前,我们要考虑:

  (1)如果是第一次执行 scp 需要确认服务器公钥,如果不是第一次执行则无需这一步

  (2)timeout 时间设定,当拷贝大文件时,timeout设置的过短会造成文件没有完全的传输完成。

在编写脚本的时,需要考虑以上问题,脚本如下:

#!/usr/bin/expect
set timeout 3
set host "192.168.118.15"
set username "root"
set password "123456" # 使用spawn 启动一个新进程执行 scp 命令
spawn scp $username@$host:/root/testfile /root/ # 在这里timeout 为 3秒,超过三秒执行下一个匹配
expect "*yes/no*" {send "yes\r"}
expect "*password*" {send "$password\r"} # 在scp传输文件时,timeout时间设置为无限时,当大文件传输时,需要更多的时间
set timeout -1 # 当匹配到 传输完成 100%后,转到下一步
expect "100%" # 使用 eof 结束该进程,因为上面设置 timeout 为 -1 无限时
expect eof

执行结果:

可以看到,文件传输需要 14 秒,而上面如果设置的超时时间低于 14 秒, 则文件传输不完整。

在日常使用中,expect 结合 shell 使用,在 shell 中引用 expect 脚本如下:

#!/usr/bin/bash
...
[shell 执行脚本]
...
expect <<EOF
set timeout 3
...
[expect 执行脚本]
...
EOF
...
[shell 执行脚本]
...

例如:拷贝一个压缩包到本地,然后解压

#!/bin/bash

host="192.168.118.15"
username="root"
password="123456"
expect <<EOF
set timeout 3
spawn scp $username@$host:/root/testfile.tar.gz /root/
expect "*yes/no*" {send "yes\r"}
expect "*password*" {send "$password\r"}
set timeout -1
expect "100%"
expect eof
EOF
echo '开始解压...'
tar xf testfile.tar.gz
if [ $? -eq 0 ]; then
echo '解压完成.'
fi

执行结果:

3.2 expect ssh执行远程命令

  ssh远程执行命令流程如下:

          

执行脚本:

#!/usr/bin/expect
set timeout 3
set host "192.168.118.15"
set username "root"
set password "123456" spawn ssh $username@$host ifconfig
expect "*yes/no*" {send "yes\r"}
expect "*password*" {send "$password\r"}
expect eof

执行结果:

expect 匹配 shell 使用还是很强大的,尤其是在没有 python 和无法连接互联网的环境中。

expect 实现自动交互脚本的更多相关文章

  1. expect实现自动交互由浅入深

    expect实现自动交互由浅入深 作为运维人员可以通过Shell可以实现简单的控制流功能,如:循环.判断等.但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet ...

  2. 自动交互脚本之expect使用记录

    之前一直没怎么用这个命令,意外用了一下,还不错,那这个是干嘛的呢 我们或多或少会远程登录其他服务器,需要执行某项任务,通常需要手动接入,输入密码啊,等等 那我们如何有效的自动执行呢,expect可以解 ...

  3. 使用expect实现自动交互,shell命令行自动输入,脚本自动化,变量引用,expect spawn执行带引号命令,expect 变量为空,不生效,不能匹配通配符*,函数,数组

    背景 有需求,在允许命令或者脚本跳出交互行,需要进行内容输入,但需要人手动输入,不是很方便,此时可以通过expect来实现自动互动交互. expect是一个自动交互功能的工具,可以满足代替我们实际工作 ...

  4. 用expect做自动应答脚本

    Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools).使用它系统管理员可以创 ...

  5. 使用expect实现自动交互,shell命令行自动输入

    背景 有需求,在允许命令或者脚本跳出交互行,需要进行内容输入,但需要人手动输入,不是很方便,此时可以通过expect来实现自动互动交互. expect是一个自动交互功能的工具,可以满足代替我们实际工作 ...

  6. Linux Expect自动交互脚本

    https://likegeeks.com/expect-command/ In the previous post, we talked about writing practical shell ...

  7. Linux--使用expect进行自动交互

    在linux下进行一些操作时,有时需要与机器进行一些交互操作,比如切换账号时输入账号密码,传输文件时输入账号密码登陆远程机器等,但有时候这些动作需要在shell脚本中进行,这个时候就可以使用expec ...

  8. 用expect做自动运行脚本

    下面的脚本演示了在Ubuntu上安装expect,写一个切换用户的expect脚本,并运行脚本看到效果的过程. root@guserver:~# apt-get install expect godu ...

  9. expect简单自动交互-用于密码、命令输入

    1. 安装expect #yum -y install expect 2. 新建.exp文件,用于ssh交换机 #vi exp.exp #!/bin/expect set f [open ipfile ...

随机推荐

  1. 3种方法实现CSS隐藏滚动条并可以滚动内容

    隐藏滚动条的同时还需要支持滚动,我们经常在前端开发中遇到这种情况,最容易想到的是加一个iscroll插件,但其 实现在CSS也可以实现这个功能,我已经在很多地方使用了,下面一起看看这三种方法. 方法1 ...

  2. springmvc文件上传AND jwt身份验证

    SpringMVC文件上传 思路:1.首先定义页面,定义多功能表单(enctype=“multipart/form-data”)2.在Controller里面定义一个方法,用参数(MultipartF ...

  3. Oracle Replace()函数与translate()函数 替换函数

    简要比较: replace 字符串级别的代替 如:SELECT REPLACE('accd','cd','ef') from dual; --> aefd translate 字符级别的代替 如 ...

  4. GreenPlum 常用命令

    gpstate 命令 参数 作用 gpstate -b => 显示简要状态 gpstate -c => 显示主镜像映射 gpstart -d => 指定数据目录(默认值:$MASTE ...

  5. input重复上传图片失效的问题

    使用input的file来上传图片 如果是重复选择相同的图片就会失效 解决的办法就是当每次上传完图片后让input的值为空就可以解决了 附上代码 只需在末尾添加这句就行$(this).val(&quo ...

  6. RookeyFrame 隐藏 首次加载菜单 的伸缩动画

    一进入系统,然后点击菜单“系统管理”,会看到展开的“系统设置”菜单,又缩回去了,每次都会有(处女座看到就想改). 隐藏这个动画的JS:jquery.easyui.min.js,这个JS里面有个方法“_ ...

  7. 洛谷 P1147 连续自然数和 题解

    P1147 连续自然数和 题目描述 对一个给定的自然数MM,求出所有的连续的自然数段,这些连续的自然数段中的全部数之和为MM. 例子:1998+1999+2000+2001+2002 = 100001 ...

  8. 【一起来烧脑】一步学会HTML体系

    [外链图片转存失败(img-zk4xNuy1-1563431241992)(https://upload-images.jianshu.io/upload_images/11158618-4e9cac ...

  9. 《挑战30天C++入门极限》入门教程:C++中的const限定修饰符

        入门教程:C++中的const限定修饰符 const修饰符可以把对象转变成常数对象,什么意思呢? 意思就是说利用const进行修饰的变量的值在程序的任意位置将不能再被修改,就如同常数一样使用! ...

  10. UOJ#316. 【NOI2017】泳池 动态规划,Berlekamp-Massey,Cayley-Hamilton定理

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ316.html 题解 首先,我们将答案转化成最大矩形大小 \(\leq k\) 的概率 减去 \(\leq k-1\) 的 ...