Как я могу держать FIFO открытым для чтения?

Я пытаюсь перенаправить стандартный ввод и стандартный вывод программы. В настоящее время я экспериментирую с макетом bash, но у меня странное поведение.

У меня есть следующее:

mkfifo in
mkfifo out

У меня также есть следующий скрипт test.sh

#!/bin/bash

while read line; do
  echo "I read ${line}"
done < /dev/stdin

В терминале 1 я делаю следующее:

tail -f out

В терминале 2 я делаю следующее:

./test.sh < in > out

В терминале 3 я делаю следующее:

echo "foo" > in
echo "bar > in

Однако вместо того, чтобы видеть, как я читаю foo, а затем я читаю bar в терминале 1, я ничего не получаю после первого эха, обе строки после второго эха, а затем программа test.sh в терминале 2 завершается. Как я могу предотвратить выход, чтобы я мог продолжать отправлять входные данные test.sh? Кроме того, вместо буферизации, а затем дампа при завершении программы, как я могу получить вывод из test.sh для сброса в хвост -f в терминале 1?


person Maxthecat    schedule 17.12.2020    source источник


Ответы (1)


Используйте перенаправление для одной составной команды, которая содержит две ваши команды echo.

{
  echo "foo"
  echo "bar"
} > in

Если, как кажется при ближайшем рассмотрении, вы хотите, чтобы in оставался открытым, пока вы выполняете команды в интерактивном режиме, используйте exec, чтобы открыть in в другом файловом дескрипторе:

exec 3> in      # Open in on file descriptor 3
echo "foo" >&3  # Write to file descriptor 3 instead of standard output
echo "bar" >&3  # "
exec 3>&-       # Close file descriptor 3

Обратите внимание, что exec 3> in будет блокироваться до тех пор, пока что-то (в вашем случае test.sh) не откроет in для чтения, и из-за буферизации вы можете не увидеть никаких выходных данных из tail -f out, пока не закроете файловый дескриптор 3.

person chepner    schedule 17.12.2020
comment
Последнее - это именно то, что я искал - спасибо! - person Maxthecat; 17.12.2020