expect命令用法示例:如何自动化shell脚本?

2021年9月16日02:53:31 发表评论 1,527 次浏览

在上一篇文章中,我们谈到了编写实用的 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命令

expect命令

在讲expect命令之前,我们先来看看一些用于交互的Expect命令:

spawn启动脚本或程序。
expect等待程序输出。
send向你的程序发送回复。
interact允许你与你的程序进行交互。
  • spawn 命令启动脚本或程序,如 shell、FTP、Telnet、SSH、SCP 等。
  • send 命令向脚本或程序发送回复。
  • Expect 命令等待输入。
  • interact命令允许你定义预定义的用户交互。

我们将输入一个询问一些问题的 shell 脚本,我们将制作一个可以回答这些问题的 Expect 脚本。

首先,shell 脚本如下所示:

#!/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

现在我们将编写将自动回答这个问题的 Expect 脚本,expect命令用法示例如下:

#!/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

第一行定义了expect命令路径,它是

#!/usr/bin/expect

.

在第二行代码中,我们禁用超时。然后使用 spawn 命令启动我们的脚本。

我们可以使用 spawn 来运行我们想要的任何程序或任何其他交互式脚本。

剩下的几行是与我们的 shell 脚本交互的 Expect 脚本。

最后一行表示交互结束。

现在 Showtime,让我们运行我们的答案机器人并确保它可以执行。

$ chmod +x ./answerbot
$./answerbot
expect命令用法示例:如何自动化shell脚本?

凉爽的!!send 命令回答了所有问题。

如果你收到有关 Expect 命令位置的错误,你可以使用 which 命令获取位置:

$ which expect

如何使用expect命令?我们根本没有与我们的脚本进行交互;Expect 程序为我们完成了这项工作。

你可以将上述方法应用于任何交互式脚本或程序。虽然上面的 Expect 脚本很容易编写,但对于某些人来说,Expect 脚本可能有点棘手,你已经知道了。

如何自动化shell脚本?使用autoexpect

要自动构建expect脚本,你可以使用 autoexpect 命令。

autoexpect 的工作方式类似于 expect 命令,但它为你构建自动化脚本。你将要自动化的脚本作为参数传递给 autoexpect,然后回答问题,autoexpect 将你的答案保存在一个文件中。

$ autoexpect ./questions
expect命令用法示例:如何自动化shell脚本?

autoexpect 生成一个名为 script.exp 的文件,其中包含与我们上面所做的相同的代码,但我们现在将保留一些附加内容。

expect命令用法示例:如何自动化shell脚本?

如果你运行自动生成的文件 script.exp,你将看到与预期相同的答案:

expect命令用法示例:如何自动化shell脚本?

惊人的!!那超级容易。

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 -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

现在尝试使用一些参数运行 Expect 脚本以查看输出:

$ ./answerbot SomeName Programming
expect命令用法示例:如何自动化shell脚本?

惊人的!!现在我们的自动化 Expect 脚本更加动态。

条件测试

你可以使用大括号编写条件测试,如下所示:

expect {

    "something" { send -- "send this\r" }

    "*another" { send -- "send another\r" }

}

如何使用expect命令?我们将更改我们的脚本以返回不同的条件,我们将更改我们的 Expect 脚本来处理这些条件。

我们将使用以下脚本模拟不同的expect:

#!/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

当你运行脚本时,它每次都会生成一个随机数,并基于该数字;我们设置了一个条件来返回不同的expect。

让我们制作将处理该问题的 Expect 脚本。

#!/usr/bin/expect -f

set timeout -1

spawn ./questions

expect {

    "*topic?" { send -- "Programming\r" }

    "*movie?" { send -- "Star wars\r" }

}

expect eof
expect命令用法示例:如何自动化shell脚本?

非常清楚。如果脚本命中主题输出,则expect脚本将发送编程,如果脚本命中电影输出,则expect脚本将发送星球大战。是不是很酷?

if-else条件

你可以在 expect 脚本中使用 if/else 子句,如下expect命令用法示例:

#!/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"

}
expect命令用法示例:如何自动化shell脚本?

注意:左大括号必须在同一行上

While 循环

expect语言中的 while 循环必须使用大括号来包含这样的表达式:

#!/usr/bin/expect -f

set NUM 0

while { $NUM <= 5 } {

    puts "\nNumber is $NUM"

    set NUM [ expr $NUM + 1 ]

}

puts ""
expect命令用法示例:如何自动化shell脚本?

For 循环

与任何脚本或编程语言一样,你可以将 for 循环用于重复性任务,必须指定三个字段,如下格式:

#!/usr/bin/expect -f

for {set NUM 0} {$NUM <= 5} {incr NUM} {

    puts "\nNUM = $NUM"

}

puts ""
expect命令用法示例:如何自动化shell脚本?

用户定义函数

你可以使用 proc 定义一个函数,如下所示:

proc myfunc { TOTAL } {

    set TOTAL [expr $TOTAL + 1]

    return "$TOTAL"

}

之后你可以使用它们。

#!/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 ""
expect命令用法示例:如何自动化shell脚本?

interact命令

expect命令自动化shell脚本:有时你的expect脚本包含一些你不想与使用你的expect脚本的其他用户共享的敏感信息,例如密码或任何其他数据。因此,你希望脚本从你那里获取此密码并正常继续自动化。

interact命令将控制权恢复到键盘。

当你使用interact命令时,expect 将开始从键盘读取。

此 shell 脚本将询问密码,如下所示:

#!/bin/bash

echo "Hello, who are you?"

read $REPLY

echo "What is you password?"

read $REPLY

echo "What is your favorite topic?"

read $REPLY

现在我们将编写将提示输入密码的 Expect 脚本:

#!/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
expect命令用法示例:如何自动化shell脚本?

键入密码后,键入 ++,控件将从键盘返回到脚本。

如何使用expect命令?由于它的简单性和重要性,Expect 语言被移植到许多语言,如 C#、Java、Perl、Python、Ruby 和 Shell,具有几乎相同的概念和语法。

如何自动化shell脚本?你可以在质量保证、网络测量(例如回声响应时间)、自动文件传输、更新和许多其他用途中使用 expect 脚本语言。

根据以上的expect命令用法示例,我希望你现在已经掌握了 expect 命令、autoexpect 命令的一些最重要的方面,以及如何使用它以更智能的方式自动化你的任务。

谢谢阅读。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: