In the previous post, we talked about writing practical shell scripts and we saw how it is easy to write a shell script. Today we are going to talk about a tool that does magic to our shell scripts, that tool is the Expect command or Expect scripting language.

 

Expect command or expect scripting language is a language that talks with your interactive programs or scripts that require user interaction.

 
 

Expect scripting language works by expecting input, then the Expect script will send the response without any user interaction.

You can say that this tool is your robot which will automate your scripts.

If Expect command if not installed on your system, you can install it using the following command:

$ apt-get install expect

Or on Red Hat based systems like CentOS:

$ yum install expect

Expect Command

Before we talk about expect command, Let’s see some of the expect command which used for interaction:

spawn                  Starting a script or a program.

expect                  Waiting for program output.

send                      Sending a reply to your program.

interact                Allowing you in interact with your program.

  • The spawn command is used to start a script or a program like the shell, FTP, Telnet, SSH, SCP, and so on.
  • The send command is used to send a reply to a script or a program.
  • The Expect command waits for input.
  • The interact command allows you to define a predefined user interaction.

We are going to type a shell script that asks some questions and we will make an Expect script that will answer those questions.

First, the shell script will look like this:

 
#!/bin/bash
 
echo "Hello, who are you?"
 
read $REPLY
 
echo "Can I ask you some questions?"
 
read $REPLY
 
echo "What is your favorite topic?"
 
read $REPLY

Now we will write the Expect scripts that will answer this automatically:

 
#!/usr/bin/expect -f
 
set timeout -1
 
spawn ./questions
 
expect "Hello, who are you?\r"
 
send -- "Im Adam\r"
 
expect "Can I ask you some questions?\r"
 
send -- "Sure\r"
 
expect "What is your favorite topic?\r"
 
send -- "Technology\r"
 
expect eof

The first line defines the expect command path which is  #!/usr/bin/expect .

On the second line of code, we disable the timeout. Then start our script using spawn command.

We can use spawn to run any program we want or any other interactive script.

The remaining lines are the Expect script that interacts with our shell script.

The last line if the end of file which means the end of the interaction.

Now Showtime, let’s run our answer bot and make sure you make it executable.

$ chmod +x ./answerbot

$./answerbot

Cool!! All questions are answered as we expect.

If you get errors about the location of Expect command you can get the location using the which command:

 

$ which expect

We did not interact with our script at all, the Expect program do the job for us.

The above method can be applied to any interactive script or program.Although the above Expect script is very easy to write, maybe the Expect script little tricky for some people, well you have it.

 

Using autoexpect

To build an expect script automatically, you can the use autoexpect command.

autoexpect works like expect, but it builds the automation script for you. The script you want to automate is passed to autoexpect as a parameter and you answer the questions and your answers are saved in a file.

$ autoexpect ./questions

A file is generated called script.exp contains the same code as we did above with some additions that we will leave it for now.

If you run the auto generated file script.exp, you will see the same answers as expected:

Awesome!! That super easy.

There are many commands that produce changeable output, like the case of FTP programs, the expect script may fail or stuck. To solve this problem, you can use wildcards for the changeable data to make your script more flexible.

 

Working with Variables

The set command is used to define variables in Expect scripts like this:

set MYVAR 5

To access the variable, precede it with $ like this $VAR1

To define command line arguments in Expect scripts, we use the following syntax:

set MYVAR [lindex $argv 0]

Here we define a variable MYVAR which equals the first passed argument.

You can get the first and the second arguments and store them in variables like this:

 
set my_name [lindex $argv 0]
 
set my_favorite [lindex $argv 1]

Let’s add variables to our script:

 
#!/usr/bin/expect -f
 
set my_name [lindex $argv 0]
 
set my_favorite [lindex $argv 1]
 
set timeout -1
 
spawn ./questions
 
expect "Hello, who are you?\r"
 
send -- "Im $my_name\r"
 
expect "Can I ask you some questions?\r"
 
send -- "Sure\r"
 
expect "What is your favorite topic?\r"
 
send -- "$my_favorite\r"
 
expect eof

Now try to run the Expect script with some parameters to see the output:

$ ./answerbot SomeName Programming

Awesome!! Now our automated Expect script is more dynamic.

Conditional Tests

You can write conditional tests using braces like this:

 
expect {
 
    "something" { send -- "send this\r" }
 
    "*another" { send -- "send another\r" }
 
}

We are going to change our script to return different conditions, and we will change our Expect script to handle those conditions.

We are going to emulate different expects with the following script:

 
#!/bin/bash
 
let number=$RANDOM
 
if [ $number -gt 25000 ]; then
 
    echo "What is your favorite topic?"
 
else
 
    echo "What is your favorite movie?"
 
fi
 
read $REPLY

A random number is generated every time you run the script and based on that number, we put a condition to return different expects.

Let’s make out Expect script that will deal with that.

 
#!/usr/bin/expect -f
 
set timeout -1
 
spawn ./questions
 
expect {
 
    "*topic?" { send -- "Programming\r" }
 
    "*movie?" { send -- "Star wars\r" }
 
}
 
expect eof

Very clear. If the script hits the topic output, the Expect script will send programming and if the script hits movie output the expect script will send star wars. Isn’t cool?

 

If else Conditions

You can use if/else clauses in expect scripts like this:

 
#!/usr/bin/expect -f
 
set NUM 1
 
if { $NUM < 5 } {
 
    puts "\Smaller than 5\n"
 
} elseif { $NUM > 5 } {
 
    puts "\Bigger than 5\n"
 
} else {
 
    puts "\Equals 5\n"
 
}

Note: The opening brace must be on the same line.

While Loops

While loops in expect language must use braces to contain the expression like this:

 
#!/usr/bin/expect -f
 
set NUM 0
 
while { $NUM <= 5 } {
 
    puts "\nNumber is $NUM"
 
    set NUM [ expr $NUM + 1 ]
 
}
 
puts ""

 

For Loops

To make a for loop in expect, three fields must be specified, like the following format:

 
#!/usr/bin/expect -f
 
for {set NUM 0} {$NUM <= 5} {incr NUM} {
 
    puts "\nNUM = $NUM"
 
}
 
puts ""

User-defined Functions

You can define a function using proc like this:

 
proc myfunc { TOTAL } {
 
    set TOTAL [expr $TOTAL + 1]
 
    return "$TOTAL"
 
}

And you can use them after that.

 
#!/usr/bin/expect -f
 
proc myfunc { TOTAL } {
 
    set TOTAL [expr $TOTAL + 1]
 
    return "$TOTAL"
 
}
 
set NUM 0
 
while {$NUM <= 5} {
 
    puts "\nNumber $NUM"
 
    set NUM [myfunc $NUM]
 
}
 
puts ""

Interact Command

Sometimes your Expect script contains some sensitive information that you don’t want to share with other users who use your Expect scripts, like passwords or any other data, so you want your script to take this password from you and continuing automation normally.

The interact command reverts the control back to the keyboard.

When this command is executed, Expect will start reading from the keyboard.

This shell script will ask about the password as shown:

 
#!/bin/bash
 
echo "Hello, who are you?"
 
read $REPLY
 
echo "What is you password?"
 
read $REPLY
 
echo "What is your favorite topic?"
 
read $REPLY

Now we will write the Expect script that will prompt for the password:

 
#!/usr/bin/expect -f
 
set timeout -1
 
spawn ./questions
 
expect "Hello, who are you?\r"
 
send -- "Hi Im Adam\r"
 
expect "*password?\r"
 
interact ++ return
 
send "\r"
 
expect "*topic?\r"
 
send -- "Technology\r"
 
expect eof

After you type your password type ++ and the control will return back from the keyboard to the script.

Expect language is ported to many languages like C#, Java, Perl, Python, Ruby and Shell with almost the same concepts and syntax due to its simplicity and importance.

Expect scripting language is used in quality assurance, network measurements such as echo response time, automate file transfers, updates, and many other uses.

I hope you now supercharged with some of the most important aspects of Expect command, autoexpect command and how to use it to automate your tasks in a smarter way.

Thank you.

示例:

#!/bin/bash 

passwd=*********
ips=`cat /tmp/ip.list|awk '{print $1}'` for host in $ips do expect <<!
spawn rsync -av list.txt002 root@$host:/tmp expect {
"Are you sure you want to continue connecting (yes/no)? " { send "yes\r"; exp_continue}
"password:" { send "$passwd\r"; exp_continue}
}
! done

  

Expect Command And How To Automate Shell Scripts Like Magic的更多相关文章

  1. 鸟哥的 Linux 私房菜Shell Scripts篇(一)

    参考: http://linux.vbird.org/linux_basic/0340bashshell-scripts.php#script_be http://www.runoob.com/lin ...

  2. 第十三章、学习 Shell Scripts

    什么是 Shell scripts shell script (程序化脚本) :shell script 是针对 shell 所写的『脚本!』 shell script 是利用 shell 的功能所写 ...

  3. source command not found in sh shell解决办法

    在Ubuntu系统中执行脚本的时候突然出现错误"source command not found in sh shell" 这个其实在Ubuntu 当中 执行脚本默认的使用的是da ...

  4. React native采坑路 Running 1 of 1 custom shell scripts

    1. Running 1 of 1 custom shell scripts 卡住的问题. 分析: 四个文件没有下载完成. boost_1_63_0.tar.gz folly-2016.09.26.0 ...

  5. 鸟哥的Linux私房菜——第十六章:学习Shell Scripts

    视频链接:http://www.bilibili.com/video/av10565321/ 1. 什么是 Shell Script       (shell写的脚本)1.1 干嘛学习 shell s ...

  6. 鸟哥的Linux私房菜-第10/11/12/13章(vim程序编辑器、学习bash、正则表达式与文件格式化处理、学习Shell Scripts)

    第10章 vim程序编辑器 可以将vim看做vi的进阶版本,vim可以用颜色或底线等方式来显示出一些特殊的信息. 为何要学习vim?因为: a. 所有的 Unix Like 系统都会内建 vi 文书编 ...

  7. linux source命令与sh shell scripts的区别

    source FileName 作用:在当前bash环境下读取并执行FileName中的命令. 注:该命令通常用命令“.”来替代. 如:source .bash_rc 与 . .bash_rc 是等效 ...

  8. 鸟哥的linux私房菜——第十二章学习(Shell Scripts)

    第十二章  Shell Scripts 1.0).什么是shell scripts? script 是"脚本.剧本"的意思.整句话是说, shell script 是针对 shel ...

  9. 第十三章、学习 Shell Scripts 简单的 shell script 练习

    简单的 shell script 练习 简单范例 对谈式脚本:变量内容由使用者决定 [root@www scripts]# vi sh02.sh #!/bin/bash # Program: # Us ...

随机推荐

  1. 【05】C#特有的ref、out参数

    java和C#非常相似,它们大部分的语法是一样的,但尽管如此,也有一些地方是不同的. 为了更好地学习java或C#,有必要分清它们两者到底在哪里不同. 我们这次要来探讨C#特有的ref.out参数. ...

  2. 需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping。

    问题: 该错误是因为应用程序需要jQuery,但是当前项目中并没有jQuery,或者存在jQuery但是程序不知道jQuery的存放路径. 解决方案: 一.下载jQuery,引入必要的jquery-X ...

  3. C#使用Redis实现网站统计访问数或点赞数功能!

    1.安装.net操作Redis需要的NuGet包: 这里推荐使用:StackExchange.Redis,在程序包管理器控制台输入命令install-package stackexchange.red ...

  4. xampp windows10下xdebug调试环境安装及配置

    xampp是在windows环境下做php,mysql开发的全家桶,免去了很多apache, php集成配置,数据库驱动安装配置的过程,应用非常广泛. xdebug是php开发调试必备利器,本文就记录 ...

  5. iis url 重写

    1.选择网站-找到有测url 重写 :2:选中它,在右上角有一个打开功能,点击打开 3.依然在右上角,点击添加规则 4:选择第一个,空白规则 名称随便输入,我们通常有这样一个需求,就是.aspx 后缀 ...

  6. 分析mybatis中 #{} 和${}的区别

    分析方法: 在 GenericTokenParser这个类的parse方法的这一行下个断点调试一下就明白了 builder.append(handler.handleToken(content)); ...

  7. 高性能TcpServer(Java) - Netty

    源码下载 -> 提取码  QQ:505645074 Netty 是一个高性能.异步事件驱动的 NIO 框架,它提供了对 TCP.UDP 和文件传输的支持,作为一个异步 NIO 框架,Netty ...

  8. VMWare共享文件夹使用

    1. 先在windows中创建一个文件夹,使用英文名称. 2. VMWare中,菜单栏 虚拟机->设置 3. Linux中的访问目录  /mnt/hgfs/winshare winshare  ...

  9. Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置

    Asp.Net SignalR 使用记录   工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...

  10. HBase安装指南

    一.事前准备 此安装是建立在hadoop集群运行起来的基础上,此hadoop版本为2.6.0,其他版本未测试,可能存在兼容性问题. 上传所需文件到/usr/local/soft   二.zookeep ...