我在运行bash shell的Linux终端中使用交互式命令行程序.我有一个确定的命令序列,我输入到shell程序.程序将其输出写入标准输出.其中一个命令是'save'命令,它将上一个运行的命令的输出写入文件到磁盘.
典型的周期是:
$prog
$$cmdx
$$<some output>
$$save <filename>
$$cmdy
$$<again, some output>
$$save <filename>
$$q
$<back to bash shell>
Run Code Online (Sandbox Code Playgroud)
如何自动完成此过程?我想写一个shell脚本,可以启动这个程序,循环执行这些步骤,逐个输入命令,然后退出.我希望save命令正常工作.
Tri*_*tan 15
如果你的命令不关心你输入的速度有多快,而你真的不需要与它进行交互,那么你可以使用heredoc.
例:
#!/bin/bash
prog <<EOD
cmdx
save filex
cmdy
save filey
q
EOD
Run Code Online (Sandbox Code Playgroud)
如果您需要根据程序的输出进行分支,或者您的程序对命令的时间敏感,那么Expect就是您想要的.
哪里有需要,有办法!我认为,看看流程管理和ipc是如何工作的,这是一个很好的bash课程.当然,最好的解决方案是Expect.但真正的原因是管道可能很棘手,许多命令都是为了等待数据而设计的,这意味着由于难以预测的原因,该过程将变成僵尸.但是学习如何以及为什么让我们想起引擎盖下发生的事情.
当两个进程进行对话时,危险在于其中一个或两个将尝试读取永远不会到达的数据.参与规则必须清晰明了.像CRLF和字符编码之类的东西可以杀死派对.幸运的是,像bash脚本和子进程这样的两个密切合作伙伴相对容易保持一致.最容易遗漏的是bash正在为它所做的每一件事启动一个子进程.如果你能用bash工作,你就完全知道自己在做什么.
关键是我们想要与另一个流程进行对话.这是一个服务器:
# a really bad SMTP server
# a hint at courtesy to the client
shopt -s nocasematch
echo "220 $HOSTNAME SMTP [$$]"
while true
do
read
[[ "$REPLY" =~ ^helo\ [^\ ] ]] && break
[[ "$REPLY" =~ ^quit ]] && echo "Later" && exit
echo 503 5.5.1 Nice guys say hello.
done
NAME=`echo "$REPLY" | sed -r -e 's/^helo //i'`
echo 250 Hello there, $NAME
while read
do
[[ "$REPLY" =~ ^mail\ from: ]] && { echo 250 2.1.0 Good guess...; continue; }
[[ "$REPLY" =~ ^rcpt\ to: ]] && { echo 250 2.1.0 Keep trying...; continue; }
[[ "$REPLY" =~ ^quit ]] && { echo Later, $NAME; exit; }
echo 502 5.5.2 Please just QUIT
done
echo Pipe closed, exiting
Run Code Online (Sandbox Code Playgroud)
现在,希望能够发挥魔力的脚本.
# Talk to a subprocess using named pipes
rm -fr A B # don't use old pipes
mkfifo A B
# server will listen to A and send to B
./smtp.sh < A > B &
# If we write to A, the pipe will be closed.
# That doesn't happen when writing to a file handle.
exec 3>A
read < B
echo "$REPLY"
# send an email, so long as response codes look good
while read L
do
echo "> $L"
echo $L > A
read < B
echo $REPLY
[[ "$REPLY" =~ ^2 ]] || break
done <<EOF
HELO me
MAIL FROM: me
RCPT TO: you
DATA
Subject: Nothing
Message
.
EOF
# This is tricky, and the reason sane people use Expect. If we
# send QUIT and then wait on B (ie. cat B) we may have trouble.
# If the server exits, the "Later" response in the pipe might
# disappear, leaving the cat command (and us) waiting for data.
# So, let cat have our STDOUT and move on.
cat B &
# Now, we should wait for the cat process to get going before we
# send the QUIT command. If we don't, the server will exit, the
# pipe will empty and cat will miss its chance to show the
# server's final words.
echo -n > B # also, 'sleep 1' will probably work.
echo "> quit"
echo "quit" > A
# close the file handle
exec 3>&-
rm A B
Run Code Online (Sandbox Code Playgroud)
请注意,我们不是简单地在服务器上转储SMTP命令.我们检查每个响应代码以确保一切正常.在这种情况下,事情将不会好,脚本将保释.
| 归档时间: |
|
| 查看次数: |
19976 次 |
| 最近记录: |