1. 介绍
1.1 Expect 简介
Expect 是一个命令行工具,可以自动处理需要人工交互的命令行程序。例如,它可以自动输入密码来执行 SSH、FTP 或 Telnet 等命令。简单来说,Expect 就像一个"自动应答器",它根据命令行提示自动输入预设的回应。
Expect 的工作方式如下:首先,它发送一个命令或数据到命令行程序;它等待程序的回应;如果程序的回应符合预期,Expect 就发送下一步的命令或数据,否则它可以处理异常情况。
当时考虑使用这个命令是因为有个4G modem的AT指令需要设置
2. 安装与配置
2.1 Expect 安装
在 Debian 或 Ubuntu 系统中,可以使用如下命令安装 Expect:
sudo apt-get install expect
2.2 Expect 配置
Expect 的配置主要在编写脚本时进行。在 Expect 脚本中,通常需要配置一些预期的回应以及相应的命令或数据。
3. 基础使用
3.1 Expect 的基本命令
Expect 的基本命令主要有:
spawn
:启动新的进程send
:向进程发送字符串expect
:等待进程输出特定的字符串
一个简单的 Expect 脚本如下:
#!/usr/bin/expect spawn ssh user@hostname expect "password:" send "password\r" expect "$ " send "ls\r"
这个脚本会自动登录 SSH 并执行 ls 命令。
3.2 Expect 的控制流程
在 Expect 脚本中,可以使用条件判断和循环结构。例如:
#!/usr/bin/expect spawn ssh user@hostname expect { "password:" { send "password\r" exp_continue } "Permission denied" { send_user "Invalid password\n" exit } "$ " { send "ls\r" } }
这个脚本会在密码错误时退出,并给出提示。
4. 进阶使用
4.1 处理用户交互
Expect 可以捕获和处理用户输入。例如,可以让用户输入密码,而不是直接在脚本中写死:
#!/usr/bin/expect stty -echo send_user "Password: " expect_user -re "(.*)\n" stty echo send_user "\n" set password $expect_out(1,string) spawn ssh user@hostname expect "password:" send "$password\r" expect "$ " send "ls\r"
4.2 处理错误和异常
Expect 可以捕获和处理错误和异常。例如:
#!/usr/bin/expect spawn ssh user@hostname expect { timeout { send_user "Connection timed out\n" exit } "password:" { send "password\r" } }
这个脚本会在连接超时时给出提示并退出。
5. 实例学习
5.1 自动登录 SSH
前面的例子中已经展示了如何自动登录 SSH,这在自动化管理多台服务器时非常有用。
5.2 自动化 FTP 传输
Expect 也可以用来自动化 FTP 传输。例如:
这个脚本会自动下载 ftp.example.com 的 /pub/file.txt 文件。
#!/usr/bin/expect spawn ftp ftp.example.com expect "Name" send "username\r" expect "Password" send "password\r" expect "ftp>" send "cd pub\r" expect "ftp>" send "get file.txt\r" expect "ftp>" send "bye\r"
Expect 命令和语法规则
Expect 脚本结构
Expect 脚本通常以 #!/usr/bin/expect
开头,这告诉系统使用 Expect 解释器来执行此脚本。
基本命令
以下是 Expect 脚本中的一些基本命令:
1. spawn
spawn
命令用于启动新的进程。
spawn command
2. send
send
命令用于向进程发送字符串。
send "string"
例如,要向进程发送回车符,可以使用:
send "\r"
3. expect
expect
命令用于等待进程输出特定的字符串。
expect "string"
expect
命令还可以配合其他命令和条件,以执行更复杂的操作:
expect { "string1" { # 执行某个操作 } "string2" { # 执行另一个操作 } }
4. exp_continue
exp_continue
命令用于在 expect
块中继续等待其他字符串。
expect { "string1" { # 执行某个操作 exp_continue } "string2" { # 执行另一个操作 } }
这会在匹配到 "string1" 后,继续等待匹配 "string2"。
5. interact
interact
命令用于将用户与 spawn
的进程进行交互。当脚本执行到 interact
时,用户可以直接与进程交互,就像直接运行这个进程一样。
interact
控制结构
Expect 脚本支持以下控制结构:
1. if
条件判断:
if {condition} { # 执行某个操作 } else { # 执行另一个操作 }
2. for
循环:
for {set i 0} {$i < 10} {incr i} { # 执行循环操作 }
3. while
循环:
while {condition} { # 执行循环操作 }
变量
在 Expect 脚本中,可以使用 set
命令设置变量:
set variable_name value
要访问变量的值,可以使用 $variable_name
。
获得进程输出
Expect 可以将进程的输出存储在变量中,以便后续处理。这可以通过 $expect_out(buffer)
或 $expect_out(0,string)
等形式实现:
expect "string" set output $expect_out(buffer)
Expect 还支持使用正则表达式匹配
输出,并将匹配的子串存储在 $expect_out(1,string)
、$expect_out(2,string)
等变量中:
expect -re "(string1)(string2)" set output1 $expect_out(1,string) set output2 $expect_out(2,string)
以上就是 Expect 的主要命令和语法规则。