bash - 将第二个脚本的特定输出重定向回第一个程序的stdin?

时间:2011-07-21 10:31:01

标签: bash stdout pipe stdin stderr

我有一个小程序,让我们称它为“程序”,简单,具有“正常”行为。它从stdin获取信息(通常由用户在键盘中输入)并通过stdout / stderr打印出来。我想自动化一个进程,因此将stdout / stderr重定向到“我的小bash脚本”(也可能是C / C ++中的另一个程序)。它将它作为标准输入并过滤它。这意味着遗漏了不重要的信息..并添加了由bash脚本本身生成的更多信息。输出显示在屏幕上(由echo命令打印出来)。

到目前为止这是有效的:

program --verbose 2>&1 | ./mylittlebashscript.sh

方案:

 stdin     +---------------+              +---------------+
 --------->|               |--stdout--+-->|      my       |-->screen
           |    program    |          |   |    little     |
           |               |--stderr--|   |  bash script  |
           +---------------+              +---------------+

现在我想更进一步: 程序期望用户输入我想通过我的小bash脚本自动提供。例如,它会提示用户输入特定文件的路径。该路径由我的小bash脚本知道,bash脚本知道程序何时等待输入(因为打印出的最后一行包含“greped”的内容)。如何从我的bash脚本中管出一些信息?我不想管道所有stdout,因为只需要在屏幕上显示几个信息,程序就不会喜欢这个输出。

新方案:

 (stdin?)  +---------------+              +---------------+   (stdout?)
 -------+->|               |--stdout--+-->|      my       |-->screen
        |  |    program    |          |   |    little     |
        |  |               |--stderr--+   |  bash script  |----+(maybe
        |  +---------------+              +---------------+    | stderr?)
        |                                                      |
        +------------------------------------------------------+

目前我还不熟悉Linux。我想有可能使用猫,飞思卡,三通和管道/重定向。不幸的是,到目前为止我还没有把它变为现实。

我真的很高兴看到一个小例子! 非常感谢你!

干杯 的Matthias

PS:我认为这个帖子是相关的:how to redirect stdout of 2nd process back to stdin of 1st process?

修改 好的,为了更详细的解释,我从我的测试机器上拿走了我的测试文件:

我将另一个名为 input.sh 的批处理文件替换为“program”:

#!/bin/bash
echo "input.sh: give me input, waiting for input 1"
read x
echo $x
echo "input.sh: give me input, waiting for input 2"
read x
echo $x

我得到了第二个(“mylittlebashscript.sh”),现在称为 inter.sh 来处理:

#!/bin/bash
echo "inter.sh: start"
while read line ; do
  echo "inter.sh: line>$line"
  notfound=$(echo $line | grep "waiting")
  if [[ "$notfound" ]]; then
    echo "inter.sh: input sh seems to wait for input! putting something in the fifo"
    #echo "banana" > testfile
    #echo "I am the stderr" >&2
  fi

done
echo "inter.sh: end"
exit

6 个答案:

答案 0 :(得分:3)

你有没有尝试过,你联系的主题是答案:

mkfifo fifo
program --verbose < fifo 2>&1 | ./mylittlebashscript.sh | tee fifo

也许,你应该让你的脚本在等待输入之前打印出一些文本,以避免卡在等待循环中。

答案 1 :(得分:3)

其他类似expect的软件工具将是empty

http://empty.sourceforge.net

答案 2 :(得分:2)

这听起来像是expect的工作!使用expect脚本,您可以从expect脚本启动该程序,该脚本充当一个包装器,用于侦听stdout中的某些模式,并将内容输入到stdin中作为响应。例如,一个能够回答input.sh脚本的摘录:

#!/usr/bin/expect -f

spawn input.sh
expect ".+input 1"
send "something cool\r"
expect ".+input 2"
send "also cool\r"
expect eof

答案 3 :(得分:2)

您可能还需要考虑此类任务的客户端/服务器模型。

请参阅:BASH: Best architecture for reading from two input streams

一般情况下,如果input.sh的标准输入不是终端(而是从fifo重定向),则必须从控制终端设备/dev/tty明确读取以启用/获取用户输入

read x < /dev/tty  # in input.sh

./input.sh < fifo 2>&1 | ./inter.sh 2>fifo

答案 4 :(得分:2)

这是一个小的empty代码段,用于编写Bash中的简单telnet会话。

# http://empty.sourceforge.net
cd empty-0.6.18b && man ./empty.1
empty -h 
empty -f -L >(tee empty.log) telnet
empty -l

empty -s <<EOF
display
status
help
quit
EOF

empty -k
cat empty.log

答案 5 :(得分:0)

如果您的自动用户输入要求不是太复杂,也许还可以使用以下方法。

#!/bin/bash
# input.sh
echo "input.sh being busy ..."
sleep 10
echo "input.sh: give me input, waiting for input 1"
read x #</dev/tty
echo $x
echo "input.sh: give me input, waiting for input 2"
read x #</dev/tty
echo $x
echo "input.sh continuing ..."


(
echo a
sleep 1
echo b
sleep 1
exec 1>/dev/tty  # redirect anything that would go to stdout/pipe to the screen
ls
#./mylittlebashscript.sh
#./inter.sh
) | ./input.sh   # do not read from /dev/tty in input.sh