问题描述
环境:Linux/Docker,bash 版本 4.2。
问题:
-
server-app
通过交互式 shell 接受命令。 -
server-app
通过管道接收来自client.sh
的命令。 -
server-app
写入client.sh
收到的标准输出。 -
client.sh
考虑server-app
的输出以确定进一步的命令。 -
server-app
也可能要求输入密码 => 也就是说,终端的标准输入必须与server-app
的输出一起转发到client.sh
。
我使用 coproc
尝试了多种设置。但是,我要么陷入停滞状态,要么
没有收到数据。如何在 bash
中实现如下所示的设置?
.------>------------------------.
.---------. | .------------. stdin | .-----------.
| user |-------' | server-app |<-------+-------| client.sh |
| console |<--+-------------| | .--------->| |
'---------' | stdout '------------' | '-----------'
'--------------------------------'
我的尝试:
coproc server.app
function expect { local expectation=$1
# read from pipe until $expectation occurs in the input stream
# when found,echo the line to 'stdout'
echo "EXPECT: '$expectation'"
while true; do
read text <&"${copROC[0]}"
if [[ "$text" == *"$expectation"* ]]; then
echo $text
break
fi
done
}
function send { local command=$1
# send $command through pipe
echo "SEND: $command"
echo "$command" >&"${copROC[1]}"
}
expect "Conected to URL"
send "open"
expect "Session keepalive"
send "session open"
# use the reported session identifier to setup the user command
session_n=$(expect "Identifier of Session created" | cut -d' ' -f5)
command=$(echo "$user_command" | sed -e "s/SESSION/$session_n/g")
最后三行仅演示了 server-app
的可能处理
输出。这又有什么问题呢?怎样才能让它发挥作用。
解决方法
正如@sexpect 所提到的,解决问题的“自然”方法是expect。此工具将基于 Tcl 的脚本作为输入。
spawn server-app
会在expect的控制下启动server-app
。 expect
也是这些脚本中的关键字。
expect -re "something (..)"
等待与表达式 something (..)
匹配的输出。
send ...
向应用程序发送一些字符。
expect_tty ...
从启动期望脚本的用户那里获取一些输入。