mkfifo - создайте файл, который никогда не испытывает EOF и т. д. - PullRequest
0 голосов
/ 08 мая 2018

У меня есть этот скрипт:

mkfifo foo
exec 3<>foo
cat <&3 | while read line; do echo " [prepend] $line"; done &

echo "foo" >&3
echo "bar" >&3
echo "baz" >&3

Я просто пытаюсь добавить строку к каждой строке stdout / stderr каждой команды.

Проблема в том, что для именованного канала будет EOF, поэтому команда cat будет быстро завершена.

Есть ли какой-нибудь файл, который я могу использовать вместо именованного канала, который никогда не будет испытывать EOF? Так что команда cat, использованная против нее, в принципе никогда не завершится?

Я мог бы использовать tail -f вместо cat, но я считаю, что tail -f иногда бывает вялым.

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Чтобы делать то, что я хочу, это, вероятно, более простая техника:

https://unix.stackexchange.com/questions/442461/using-process-substitution-only-send-stderr-to-process

exec 2> >( while read line; do echo " stderr: $line"; done )
exec > >( while read line; do echo " stdout: $line"; done )

echo "rolo"
echo "cholo" >&2

вызовы exec настроят все так, что stdout и stderr для скрипта будут установлены для процессов в подстановках процессов.

0 голосов
/ 08 мая 2018

Как упомянуто @EmilyE. в комментарии cat продолжает работать после выхода из скрипта.

[STEP 101] # cat bar.sh
rm -f foo
mkfifo foo
exec 3<>foo
cat <&3 | while read line; do echo " [prepend] $line"; done &

echo "foo" >&3
echo "bar" >&3
echo "baz" >&3
[STEP 102] # ps
   PID TTY          TIME CMD
109338 pts/71   00:00:00 bash
109579 pts/71   00:00:00 ps
[STEP 103] # bash bar.sh
[STEP 104] #  [prepend] foo
 [prepend] bar
 [prepend] baz

[STEP 105] # ps
   PID TTY          TIME CMD
109338 pts/71   00:00:00 bash
109583 pts/71   00:00:00 cat           <-- still running
109584 pts/71   00:00:00 bash
109585 pts/71   00:00:00 ps
[STEP 106] # kill 109583
[STEP 107] #

Не уверен, что вы действительно хотите сделать, но я думаю, вам нужно явно указать while read, чтобы завершить. Например:

[STEP 108] # cat foo.sh
rm -f foo
mkfifo foo
exec 3<>foo
while read -u3 line; do
    if [[ $line == BYE ]]; then
        break
    else
        echo "[prepend] $line"
    fi
done &

echo "foo" >&3
echo "bar" >&3
echo "baz" >&3
echo "BYE" >&3

wait
[STEP 109] # bash foo.sh
[prepend] foo
[prepend] bar
[prepend] baz
[STEP 110] #
...