用脚本实现交互式命令的输入 - 转载
用脚本实现交互式命令的输入 - 转载
常规输入:回车、Yes/No 等
cat + 文件 + 管道符
cat commend.txt | apt-get install ssh
echo + 管道符
echo -e "Y" | apt-get remove ssh
echo -e
处理转义字符
有时候,你需要多次输入,就可以使用多个管道符,比如数据库的命令行客户端:
echo exit | echo start /ansible/distData/appdata/dmdb/database_dm.sql | ./disql SYSDBA/SYSDBA
expect
安装:
sudo apt-get install expect
编写 expect 文件如:注意后缀为 .expect
#! /usr/bin/expect
set timeout 0
spawn apt-get remove ssh
expect "Yes or No:"
send "Y\r"
interact
解释:
#! /usr/bin/expect
这个跟 bash shell 开头一样,是告诉系统使用那个解释器来解释脚本
注意:这一行需要在脚本的第一行。set timeout 0
设置超时时间为 0(秒)spawn sudo apt-get update
它主要的功能是给后面的 shell 语句运行进程加个壳,用来传递交互指令。expect " "
意思是判断上次输出结果里是否包含 " " 的字符串,如果有则执行下一步,否则就等待一段时间 (timeout)。send "xxx\r"
这里就是发送交互信息,与手动输入相同。 命令字符串结尾加上\r
,如果出现异常等待的状态可以核查一下。interact
执行完成后保持交互状态,把控制权从 expect 交会给 shell,shell 就可以执行 spawn 加壳的命令。
没有这句的话,即使已经成功输入,也不会执行 shell 命令,因为控制权还是 expect 手里,而 expect 是不能解释 shell 命令的。
运行方式:
./test3.expect
或者
expect test3.expect
日志:
root@ type-ThinkPad-T480s:/home/type# ./test3.expect
spawn apt-get remove ssh
Y
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
下列软件包将被【卸载】:
ssh
升级了 0 个软件包,新安装了 0 个软件包,要卸载 1 个软件包,有 8 个软件包未被升级。
解压缩后将会空出 98.3 kB 的空间。
(正在读取数据库 ... 系统当前共安装有 304178 个文件和目录。)
正在卸载 ssh (1:7.2p2-4) ...
重定向 + 文件
apt-get install ssh < commend.txt
特殊地,当一个 shell 命令需要多个参数时,以 echo 为例,用\n 来区分多个参数,例如 parasoft 安装时在不同阶段共需要 7 次交互,可以用以下命令来代替手动操作:
echo -e "1\n\n\n\n\n\n" | ./parasoft_cpptest_professional-2020.1.0.20200422B856-linux.x86_64.sh
比如我们在 TSL证书#通过 OpenSSL 进行自签名证书 中提到的
echo -e "CN\nWH\nWC\nHW\nTX\n${local_ip}\n\n\n" | openssl req -new -key private.key -out ssl.csr
其实
echo -e 'A\nB\n' | COMMAND
等同于创建一个 command.txt
:
A
B
然后执行:
COMMAND < command.txt
密码
expect
#! /usr/bin/expect
set timeout 0
spawn sudo apt-get update
#expect "Password:"
send "******\r" # your password
interact
EOF 文本块
#! /bin/bash
sudo -S mkdir test <<EOF
****** # your password
EOF
终端控制
模拟:timeout
timeout 5 apt-get remove ssh
也适用于输入密码
(base) :~$ timeout 5 su root
密码: (base) :~$
杀死进程
su root &
pid=$!
kill -SIGSTOP $pid
-SINGSTOP → CTRL+Z
-SIGINT → CTRL+C
实例:docker build 自动在镜像中安装 parasoft 及其依赖环境。
其他
若是 apt-get,可以通过 apt-get -y xxx
来执行自动确认,而无需用 echo 或 expect。