linux - 自动 bash 脚本交互
问题描述
我一直在尝试制作一个与程序交互的 bash 脚本。
我需要运行“script1”(程序,即“./script1.sh”),我需要运行“script2”(bash 脚本)并阅读问题,并回答答案,返回“script1” .
这是我无法解决的两个脚本之间的实际交互。
限制:
- 不允许使用
expect
或其他类似功能,必须在 linux shell 命令上运行。 - script1.sh 将在让步中启动几个随机生成的问题。每个都必须正确回答。
我尝试过使用一系列技术:
/proc/[pid]/fd/0
(用于使用标准输入,但似乎仅限于终端而不是 shell 进程本身)- 使用 netcat 设置管道(这可行,但在交互方面让我回到第一方:阅读和回复)
- 使用管道 (
./script1.sh | the_pipe
,但这不允许将任何输入返回给“script1”) - 使用普通文件进行输入(
./script1.sh < answer.txt > question.txt
,但似乎answer.txt
只在脚本启动时读取一次?) - 使用命名管道 (
./script1.sh < answer.pipe > question.pipe
,但由于 answer.pipe 阻止它,脚本在启动时停止。如果我强制回车到 answer.pipe 以启动进程,“script1”失败,因为回车是错误的答案) - 我曾尝试使用后台进程来分解不同的任务(即
./script_to_parse_questions.sh &
,然后将结果保存到文件中,该文件被读取一次然后被删除等)
我认为“linux方式”可能是使用管道“|” 或括号“<>”,但可能只有我无法使其正常工作。
(为澄清而编辑)
解决方案
这是您想要使用 bash Coprocess的地方(在 bash v4.0 -- NEWS中引入)
假设我们有一个包含问题和答案的文件:
$ cat q_and_a
Q1
answer one
this is question two
ans 2
question the third
I say thrice
然后“script1”就可以读取这个文件,按随机顺序提问,就知道正确答案是什么了:
$ cat script1.sh
#!/usr/bin/env bash
# read the q_and_a file
qs=()
as=()
while read -r q; read -r a; do
qs+=( "$q" )
as+=( "$a" )
done < q_and_a
# ask the questions in random order
readarray -t order < <(
printf "%d\n" "${!qs[@]}" | shuf
)
for i in "${order[@]}"; do
echo "${qs[i]}"
read -r ans
if [[ $ans == "${as[i]}" ]]; then
echo "answer to '${qs[i]}' is CORRECT"
else
echo "answer to '${qs[i]}' is WRONG"
fi
done
现在,“script2”可以调用 script1 作为协同进程,监听一个问题,提供答案,然后监听对答案的响应:
$ cat script2.sh
#!/usr/bin/env bash
# read the q_and_a file
declare -A qa
while read -r q; read -r a; do
qa[$q]=$a
done < q_and_a
coproc ./script1.sh
for ((i=0; i < ${#qa[@]}; i++)); do
read -r question <& ${COPROC[0]}
echo "script1 asked: '$question'"
echo "answering: '${qa[$question]}'"
echo "${qa[$question]}" >& ${COPROC[1]}
read -r response <& ${COPROC[0]}
echo "script1 responded: '$response'"
done
运行 script2 可能如下所示:
$ ./script2.sh
script1 asked: 'this is question two'
answering: 'ans 2'
script1 responded: 'answer to 'this is question two' is CORRECT'
script1 asked: 'question the third'
answering: 'I say thrice'
script1 responded: 'answer to 'question the third' is CORRECT'
script1 asked: 'Q1'
answering: 'answer one'
script1 responded: 'answer to 'Q1' is CORRECT'
可能在您的情况下,您可能没有包含问题和答案的共享文件,但是由于 script2 有问题,您可以做您需要做的事情来分析它并提供适当的答案。
推荐阅读
- c# - 数据表用 null 替换不正确的行
- ios - 无法将编码的 json Data 对象写入 Swift 5 中的本地文件
- python - 使用 Dask 连接巨大的 csv 文件
- usb - 如何更新 Gravio USB Zigbee IoT Dongle 的固件?
- forms - Access 2016中如何使用表单填写同一张表中相同值的字段?
- python - 尝试后缩进,除了多个for循环python
- android-studio - 如何从 Anko 的异步中获取值?(科特林)
- perl - 从另一个 Perl 程序调用 Perl 模块
- python - 关于 else 和 elseif 的 Python 问题
- python - 以适当的格式显示日期列表