blog-web/source/_posts/linux/expect-交互式命令行自动化执行.md
2018-05-14 17:02:50 +08:00

104 lines
2.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: expect-交互式命令行自动化执行
date: 2018-5-14 10:45:12
tags:
- linux
categories:
- linux
---
linux当中存在很多交互式的命令行
简单来说就是执行过程中需要等待用户的输入 , 获得输入内容后继续执行
这种情况下我们可以借助`expect`来实现自动化执行这些命令
> 直接重定向输入流多数情况下是不行的
因为它会将需要输入的内容一次性全部输入 , 而无法做到多次的交互
<!-- more -->
expect本身是一个shell脚本的解释器 , 与bash属于同一类东西
所以我们可以在脚本开头添加
```bash
#!/usr/bin/expect
```
来指定使用该解释器来执行这个脚本 , 运行脚本直接`./test.sh`即可
当然也可以执行`expect test.sh`
#### 安装
```bash
yum install expect.x86_64
```
#### 编写脚本
使用`npm init`初始化项目的时候
需要多次输入项目的相关基本信息 , 这里就用它来做示例
```bash
#!/usr/bin/expect
set timeout -1
cd /root/pro_test
spawn /usr/local/nodejs/bin/npm init
expect "package name:*"
send "\n"
expect "version:*"
send "\n"
expect "description:*"
send "这里是项目的描述信息\n"
expect "entry point:*"
send "main.js\n"
expect "test command:*"
send "\n"
expect "git repository:*"
send "\n"
expect "keywords:*"
send "key1 key2\n"
expect "author:*"
send "Sookie\n"
expect "license:*"
send "MIT\n"
expect "Is this ok?*"
send "yes\n"
expect eof
```
说明:
+ `spawn``send`命令是只有在expect解释器当中才有的 , 所以该脚本必须用expect解释执行
+ `spawn`表示启动一个新的进程
+ `expect "xxx"`表示识别的进程输出( 可以使用通配符 )
+ 注意在输入内容的末尾加`\n`
#### interact
如果我们需要让用户在适当的时候手动干预这个过程
就需要执行`interact`
例如
```bash
spawn ftp ftp.test.com
expect "Name"
send "user\n"
expect "Password:"
send "123456\n"
interact
```
下载完ftp文件时仍然可以停留在ftp命令行状态以便手动的执行后续命令
#### timeout
执行`set timeout`可以设置等待进行输出信息的超时时间
单位是秒 , 默认是10秒
如果超过了这个时间还未能匹配到输出内容 , 则会跳过这个expect语句继续向下执行
-1则表示没有超时时间 , 也就是未匹配到输出内容会一直等待
#### 多分支模式
有时候程序的输出可能有多种分支路线
所以我们的自动化脚本也不能简单地进行单线匹配
expect还支持多分支模式语法
```bash
expect {
"hi" { send "You said hi\n" }
"hello" {
send "Hello yourself\n"
expect {
"Nice to meet you" { send "Nice to meet you too!" }
"How is it going" { send "It's good, thank you." }
}
}
"bye" { send "See you\n" }
}
```