bash - перенаправить конкретный вывод из второго скрипта обратно в стандартный ввод первой программы? - PullRequest
1 голос
/ 21 июля 2011

У меня есть небольшая программа, давайте назовем ее «программа» по простоте, которая имеет «нормальное» поведение.Он берет информацию из стандартного ввода (обычно вводится пользователем на клавиатуре) и печатает через 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?Я не хочу передавать обратно весь стандартный вывод, потому что на экране должна отображаться только некоторая информация, и программа не хочет выводить ее.

Новая схема:

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

Намомент, когда я еще не очень знаком с Linux.Я предполагаю, что есть возможность работать с cat, fifos, tee и pipe / перенаправлениями.К сожалению, я до сих пор не воплотил это в жизнь.

Я был бы действительно рад маленькому примеру!Большое спасибо!

Cheers Matthias

PS: я думаю, что этот поток связан: как перенаправить стандартный вывод 2-го процесса обратно в стандартный поток 1-го процесса?

Редактировать: Хорошо, для более подробного объяснения я взял свои тестовые файлы с моей тестовой машины:

Я заменил «программу» другим пакетным файлом с именем input.sh :

#!/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 ]

3 голосов
/ 24 июля 2011

Дополнительный expect -подобный программный инструмент будет empty!

http://empty.sourceforge.net

3 голосов
/ 21 июля 2011

Пытались ли вы, в качестве ответа, связать ветку, на которую вы ссылались:чтобы не застрять в цикле ожидания ..

2 голосов
/ 22 сентября 2011

Вот небольшой empty фрагмент сценария простого telnet сеанса в Bash.

# 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
2 голосов
/ 21 июля 2011

Вы также можете рассмотреть модель клиент / сервер для такого рода задач.

См .: BASH: лучшая архитектура для чтения из двух входных потоков

В общем, если стандартный input.sh не является терминалом (а скорее перенаправлен с fifo), вы должны явно прочитать с управляющего оконечного устройства /dev/tty, чтобы включить / получить пользовательский ввод.

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

./input.sh < fifo 2>&1 | ./inter.sh 2>fifo
2 голосов
/ 21 июля 2011

Звучит как работа для 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
0 голосов
/ 26 июля 2011

Может также поиграть со следующим подходом, если ваши требования к автоматическому вводу пользователя не слишком сложны.

#!/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
...