在上一篇文章中,我们谈到了编写实用的 shell 脚本,我们看到了编写 shell 脚本是多么容易。今天我们将讨论一个对我们的 shell 脚本有魔力的工具;该工具是Expect 命令或Expect 脚本语言,结合详细的expect命令用法示例,希望可以让你更好地了解并使用它。
如何使用expect命令?Expect 命令或expect 脚本语言是一种与需要用户交互的交互式程序或脚本对话的语言。
Expect 脚本语言通过期待输入来工作,然后 Expect 脚本将在没有任何用户交互的情况下发送响应。
你可以说这个工具就是你的机器人,它会自动化你的脚本,那么如何自动化shell脚本呢?下面我们来逐渐学习。
如果你的系统上没有安装 expect 命令,你可以使用以下命令安装它:
$ apt-get install expect
或者在 CentOS 等基于 Red Hat 的系统上:
$ yum install expect
expect命令自动化shell脚本教程目录
- expect命令
- 使用autoexpect
- 使用变量
- 条件测试
- if-else条件
- While 循环
- For 循环
- 用户定义函数
- interact命令
spawn | 启动脚本或程序。 |
expect | 等待程序输出。 |
send | 向你的程序发送回复。 |
interact | 允许你与你的程序进行交互。 |
- spawn 命令启动脚本或程序,如 shell、FTP、Telnet、SSH、SCP 等。
- send 命令向脚本或程序发送回复。
- Expect 命令等待输入。
- interact命令允许你定义预定义的用户交互。
首先,shell 脚本如下所示:
#!/bin/bashecho "Hello, who are you?"read $REPLYecho "Can I ask you some questions?"read $REPLYecho "What is your favorite topic?"read $REPLY
现在我们将编写将自动回答这个问题的 Expect 脚本,expect命令用法示例如下:
#!/usr/bin/expect -fset timeout -1spawn ./questionsexpect "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
第一行定义了expect命令路径,它是
#!/usr/bin/expect
.
在第二行代码中,我们禁用超时。然后使用 spawn 命令启动我们的脚本。
我们可以使用 spawn 来运行我们想要的任何程序或任何其他交互式脚本。
剩下的几行是与我们的 shell 脚本交互的 Expect 脚本。
最后一行表示交互结束。
现在 Showtime,让我们运行我们的答案机器人并确保它可以执行。
$ chmod +x ./answerbot
$./answerbot
文章图片
凉爽的!!send 命令回答了所有问题。
如果你收到有关 Expect 命令位置的错误,你可以使用 which 命令获取位置:
$ which expect
如何使用expect命令?我们根本没有与我们的脚本进行交互;Expect 程序为我们完成了这项工作。
你可以将上述方法应用于任何交互式脚本或程序。虽然上面的 Expect 脚本很容易编写,但对于某些人来说,Expect 脚本可能有点棘手,你已经知道了。
如何自动化shell脚本?使用autoexpect要自动构建expect脚本,你可以使用 autoexpect 命令。
autoexpect 的工作方式类似于 expect 命令,但它为你构建自动化脚本。你将要自动化的脚本作为参数传递给 autoexpect,然后回答问题,autoexpect 将你的答案保存在一个文件中。
$ autoexpect ./questions
文章图片
autoexpect 生成一个名为 script.exp 的文件,其中包含与我们上面所做的相同的代码,但我们现在将保留一些附加内容。
文章图片
如果你运行自动生成的文件 script.exp,你将看到与预期相同的答案:
文章图片
惊人的!!那超级容易。
expect命令自动化shell脚本:许多命令会产生可变的输出,例如 FTP 程序,expect 脚本可能会失败或卡住。为了解决这个问题,你可以对可变数据使用通配符,使你的脚本更加灵活。
使用变量如何自动化shell脚本?你可以使用 set 命令在 expect 脚本中定义变量,如下expect命令用法示例:
set MYVAR 5
要访问变量,请在它前面加上 $ 像这样 $VAR1
要在 expect 脚本中定义命令行参数,我们使用以下语法:
set MYVAR [
lindex $argv 0]
这里我们定义了一个变量 MYVAR,它等于第一个传递的参数。
你可以获取第一个和第二个参数并将它们存储在如下变量中:
set my_name [
lindex $argv 0]set my_favorite [
lindex $argv 1]
让我们在脚本中添加变量:
#!/usr/bin/expect -fset my_name [
lindex $argv 0]set my_favorite [
lindex $argv 1]set timeout -1spawn ./questionsexpect "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
现在尝试使用一些参数运行 Expect 脚本以查看输出:
$ ./answerbot SomeName Programming
文章图片
惊人的!!现在我们的自动化 Expect 脚本更加动态。
条件测试你可以使用大括号编写条件测试,如下所示:
expect {"something" { send -- "send this\r" }"*another" { send -- "send another\r" }}
如何使用expect命令?我们将更改我们的脚本以返回不同的条件,我们将更改我们的 Expect 脚本来处理这些条件。
【expect命令用法示例(如何自动化shell脚本())】我们将使用以下脚本模拟不同的expect:
#!/bin/bashlet number=$RANDOMif [
$number -gt 25000 ];
then echo "What is your favorite topic?"else echo "What is your favorite movie?"firead $REPLY
当你运行脚本时,它每次都会生成一个随机数,并基于该数字;我们设置了一个条件来返回不同的expect。
让我们制作将处理该问题的 Expect 脚本。
#!/usr/bin/expect -fset timeout -1spawn ./questionsexpect {"*topic?" { send -- "Programming\r" }"*movie?" { send -- "Star wars\r" }}expect eof
文章图片
非常清楚。如果脚本命中主题输出,则expect脚本将发送编程,如果脚本命中电影输出,则expect脚本将发送星球大战。是不是很酷?
if-else条件你可以在 expect 脚本中使用 if/else 子句,如下expect命令用法示例:
#!/usr/bin/expect -fset NUM 1if { $NUM <
5 } {puts "\Smaller than 5\n"} elseif { $NUM > 5 } {puts "\Bigger than 5\n"} else {puts "\Equals 5\n"}
文章图片
注意:左大括号必须在同一行上。
While 循环expect语言中的 while 循环必须使用大括号来包含这样的表达式:
#!/usr/bin/expect -fset NUM 0while { $NUM <
= 5 } {puts "\nNumber is $NUM"set NUM [
expr $NUM + 1 ]}puts ""
文章图片
For 循环与任何脚本或编程语言一样,你可以将 for 循环用于重复性任务,必须指定三个字段,如下格式:
#!/usr/bin/expect -ffor {set NUM 0} {$NUM <
= 5} {incr NUM} {puts "\nNUM = $NUM"}puts ""
文章图片
用户定义函数你可以使用 proc 定义一个函数,如下所示:
proc myfunc { TOTAL } {set TOTAL [
expr $TOTAL + 1]return "$TOTAL"}
之后你可以使用它们。
#!/usr/bin/expect -fproc myfunc { TOTAL } {set TOTAL [
expr $TOTAL + 1]return "$TOTAL"}set NUM 0while {$NUM <
= 5} {puts "\nNumber $NUM"set NUM [
myfunc $NUM]}puts ""
文章图片
interact命令expect命令自动化shell脚本:有时你的expect脚本包含一些你不想与使用你的expect脚本的其他用户共享的敏感信息,例如密码或任何其他数据。因此,你希望脚本从你那里获取此密码并正常继续自动化。
interact命令将控制权恢复到键盘。
当你使用interact命令时,expect 将开始从键盘读取。
此 shell 脚本将询问密码,如下所示:
#!/bin/bashecho "Hello, who are you?"read $REPLYecho "What is you password?"read $REPLYecho "What is your favorite topic?"read $REPLY
现在我们将编写将提示输入密码的 Expect 脚本:
#!/usr/bin/expect -fset timeout -1spawn ./questionsexpect "Hello, who are you?\r"send -- "Hi Im Adam\r"expect "*password?\r"interact ++ returnsend "\r"expect "*topic?\r"send -- "Technology\r"expect eof
文章图片
键入密码后,键入 ++,控件将从键盘返回到脚本。
如何使用expect命令?由于它的简单性和重要性,Expect 语言被移植到许多语言,如 C#、Java、Perl、Python、Ruby 和 Shell,具有几乎相同的概念和语法。
如何自动化shell脚本?你可以在质量保证、网络测量(例如回声响应时间)、自动文件传输、更新和许多其他用途中使用 expect 脚本语言。
根据以上的expect命令用法示例,我希望你现在已经掌握了 expect 命令、autoexpect 命令的一些最重要的方面,以及如何使用它以更智能的方式自动化你的任务。
谢谢阅读。
推荐阅读
- NLP教程(Python NLTK用法示例和完整指南)
- 如何编写实用的shell脚本(bash编程教程)
- Codeforces348B Apple Tree DFS
- 原生APP内置PayPal网页支付方式
- Android中关于Handler Looper理解
- Android 开发第一项目——计算器的开发记录
- Android学习资源网站大全
- Android xUtils3源码解析之注解模块
- Android xUtils3源码解析之数据库模块