Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 是否可以使bashshell脚本与另一个命令行程序交互?_Linux_Bash_Shell - Fatal编程技术网

Linux 是否可以使bashshell脚本与另一个命令行程序交互?

Linux 是否可以使bashshell脚本与另一个命令行程序交互?,linux,bash,shell,Linux,Bash,Shell,我正在运行bashshell的Linux终端中使用一个交互式命令行程序。我有一个明确的命令序列,输入shell程序。程序将其输出写入标准输出。其中一个命令是“save”命令,它将运行的上一个命令的输出写入文件到磁盘 典型的循环是: $prog $$cmdx $$<some output> $$save <filename> $$cmdy $$<again, some output> $$save <filename> $$q $<back t

我正在运行bashshell的Linux终端中使用一个交互式命令行程序。我有一个明确的命令序列,输入shell程序。程序将其输出写入标准输出。其中一个命令是“save”命令,它将运行的上一个命令的输出写入文件到磁盘

典型的循环是:

$prog
$$cmdx
$$<some output>
$$save <filename>
$$cmdy
$$<again, some output>
$$save <filename>
$$q
$<back to bash shell>
$prog
$$cmdx
$$
$$保存
$$cmdy
$$
$$保存
$$q
$
  • $是bash提示符
  • $$是程序的提示
  • q是prog的quit命令
  • prog是这样的,它将上一个命令的输出附加到文件名
如何使此过程自动化?我想写一个shell脚本,可以启动这个程序,并循环执行这些步骤,一个接一个地向它发送命令,然后退出。我希望save命令能正常工作

echo "cmdx\nsave\n...etc..." | prog

…我建议您使用。此工具旨在自动化交互式shell应用程序。

如果您的命令不关心您以多快的速度为其提供输入,并且您实际上不需要与它交互,那么您可以使用herdoc

例如:

#!/bin/bash
prog <<EOD
cmdx
save filex
cmdy
save filey
q
EOD
#/bin/bash

prog对于简单用例,您可以使用子shell、echo和sleep的组合:

# in Terminal.app
telnet localhost 25
helo localhost
ehlo localhost
quit

(sleep 5; echo "helo localhost"; sleep 5; echo "ehlo localhost"; sleep 5; echo quit ) | 
   telnet localhost 25 

我使用Expect与shell交互以进行交换机和路由器备份。bash脚本使用正确的变量调用expect脚本

for i in <list of machines> ; do expect_script.sh $i ; exit
用于i-in;不要期望_script.sh$i;出口

这将ssh到每个框,运行备份命令,复制适当的文件,然后转到下一个框。

有需要的地方,就有办法!我认为这是一个很好的教训 过程管理和ipc如何工作。当然,最好的解决办法是期待。 但真正的原因是管道可能很棘手,而且许多命令都是设计的 等待数据,这意味着由于以下原因,进程将变成僵尸 这可能很难预测。但是学习如何以及为什么会提醒我们什么是 在引擎盖下进行

当两个进程进行对话时,危险在于其中一个或两个进程都会进行对话 尝试读取永远不会到达的数据。必须遵守交战规则 晶莹剔透。像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
现在,希望能发挥魔力的剧本

# 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
#使用命名管道与子流程对话
rm-fr A B#不要使用旧管道
mkfifo A B
#服务器将侦听A并发送到B
./smtp.shB&
#如果我们写信给A,管道将被关闭。
#写入文件句柄时不会发生这种情况。
行政长官3>A
阅读1美元”
回声$L>A
阅读&-
甲乙室
请注意,我们并不是简单地在服务器上转储SMTP命令。我们检查 每个响应代码确保一切正常。在这种情况下,事情就不会这样了
好的,剧本就不需要了。

这符合我的目的。我不确定标准输出会去哪里。它的行为因shell而异——请参阅,特别是应用程序使用部分:除非省略了-n(作为第一个参数)和转义序列(
\n
就是这样一个转义序列),否则不可能在所有POSIX系统中可移植地使用echo;后来:鼓励新的应用程序使用printf而不是echo。