Named Pipe преждевременно закрывается в сценарии? - PullRequest
7 голосов
/ 26 июля 2011

ls:

prwx------ 1 root root 0 fifo

write.sh:

#! /bin/bash
while true;
do
    echo "blah" > fifo
done

read.sh:

#! /bin/bash
while true;
do
    cat fifo
done

У меня два открытых терминала, один работает write.sh и еще один бег read.sh.Когда я сначала запускаю write.sh, он зависает (как и должно).Затем я иду к другому терминалу и запускаю read.sh, и он печатает "blah" тонну раз, тогда мой write.sh останавливается.Почему мой сценарий записи останавливается?Это небольшой тест, который я делаю, чтобы немного лучше понять каналы, потому что я собираюсь отправлять все свои журналы в канал, чтобы я мог проанализировать их перед записью в файл.

Что мне здесь не хватает?

Ответы [ 2 ]

5 голосов
/ 27 июля 2011

Чтобы получить неблокирующее поведение трубопровода, вы также можете сначала открыть дескриптор файла чтения, а затем дескриптор файла записи на fifo.

# cf. /2099503/troinik-asinhronno
(
rm -f fifo
mkfifo fifo
exec 3<fifo   # open fifo for reading
trap "exit" 1 2 3 15
exec cat fifo | nl
) &
bpid=$!

(
exec 3>fifo  # open fifo for writing
trap "exit" 1 2 3 15
while true;
do
    echo "blah" > fifo
done
)
#kill -TERM $bpid

См. Также: Как использовать exec3> myfifo в сценарии, а не echo foo> & 3 закрыть канал?

5 голосов
/ 26 июля 2011

Здесь есть состояние гонки.Какой бы скрипт ни выполнял свою команду внутреннего цикла первым (cat и echo соответственно), он будет блокироваться и ждать, пока другой скрипт выполнит свою команду внутреннего цикла.Однако, как только сценарии синхронизируются, если кошка вызывает close () на канале до того, как эхо выполнит свою запись (), эхо будет отправлено SIGPIPE, и ваш скрипт завершится.Вы не можете писать в канал, который был закрыт его читателем.

Если вы измените свой читатель на tail -f вместо цикла while с cat, читатель останется живым, а не откроется и закроет fifo навсегда, и вы не должны получать SIGPIPE.

ссылка: человек пятерка

...