问:
我有一个 Bash 脚本,它使用 read 命令以交互方式读取命令参数,例如 yes/no 选项。是否有一种方法可以在非交互式脚本中调用这个脚本,并将默认选项值作为参数传递?
我需要向交互式脚本传递不止一个参数。
答:
如果你的脚本是通过 read 命令在交互式环境下读取命令参数,并且你希望在非交互式脚本中传递参数,那么你可以使用以下几种方法来模拟交互式输入:
1. 使用 Here Documents
Here Documents 可以用来传递多行输入到脚本:
bash your-interactive-script.sh <<EOF
arg1
arg2
arg3
EOF
其中 arg1, arg2, 和 arg3 是对应于脚本中每一个 read 提示的输入。
2. 使用 echo 管道传递
可以通过 echo 命令和管道来传递输入值:
echo -e "arg1\narg2\narg3" | bash your-interactive-script.sh
在这里,-e 会启用对反斜杠转义的解释,\n 用于模仿输入键(ENTER)的效果。
3. 使用文件描述符
还可以使用文件描述符来模拟交互式输入:
exec 3< <(echo -e "arg1\narg2\narg3")
./your-interactive-script.sh <&3
exec 3<&-
在这里,打开了一个文件描述符 3,并将其与提供输入的进程替换关联起来。你的脚本从该文件描述符中读取内容,而不是从标准输入(stdin)中读取。
最后使用命令 exec 3<&- 关闭这个文件描述符,这样可以防止资源泄露,并确保这个文件描述符可以在脚本或程序的后续部分重新使用。
测试截图:
4. 使用 expect 工具
对于需要等待特定提示或需要更多控制的复杂场景,可以使用 expect 工具:
#!/usr/bin/expect -f
spawn ./your-interactive-script.sh
expect " 第一次提示 "
send "arg1\r"
expect " 第二次提示 "
send "arg2\r"
expect " 第三次提示 "
send "arg3\r"
interact
你可以用以下命令来安装 expect:
sudo apt-get install expect # Debian/Ubuntu 系统
#或者
sudo yum install expect # CentOS/RHEL 系统
测试截图:
总之,根据你的脚本输入场景的复杂程度来选择最合适的方法。如果只是一系列简单的输入,方法 1 和 2 是最简便的。但是,如果脚本需要更复杂的交互,expect 更合适。
参考文档: