![Процесс неожиданно завершается при отправке в именованный канал](https://rvso.com/image/154468/%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%20%D0%BD%D0%B5%D0%BE%D0%B6%D0%B8%D0%B4%D0%B0%D0%BD%D0%BD%D0%BE%20%D0%B7%D0%B0%D0%B2%D0%B5%D1%80%D1%88%D0%B0%D0%B5%D1%82%D1%81%D1%8F%20%D0%BF%D1%80%D0%B8%20%D0%BE%D1%82%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B5%20%D0%B2%20%D0%B8%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9%20%D0%BA%D0%B0%D0%BD%D0%B0%D0%BB.png)
У меня есть два процесса и один именованный канал.
Один процесс активно считывает данные из канала, а другой процесс непрерывно отправляет данные в канал.
Команда, отправляемая в канал, следующая:
sudo iotop -b -P > diskfifo
С другой стороны, считыватель просто выполняет операцию циклического чтения на канале.
pipe=./diskfifo
while read line <$pipe
do
if [[ "$line" == 'quit' ]]; then
break
fi
echo $line
done
Проблема: команда iotop иногда останавливается после определенного количества итераций, и я не могу понять, почему.
Однако я заметил, что если я уменьшаю объем отправляемых данных, команда iotop не останавливается.
решение1
На каждой итерации вашего цикла read
будет открываться канал для чтения, считываться строка данных, а затем закрываться.
Если iotop
решает попытаться записать в канал, read
не выполняя активного чтения из него, он получит сигнал PIPE
, поскольку пытается записать в канал, из которого никто не читает. Действие по умолчанию при получении сигнала PIPE
— завершение процесса.
Вместо того чтобы открывать и закрывать канал для чтения в цикле (и надеяться, что iotop
запись в канал не будет произведена, пока из него не будет производиться чтение), перенаправьте ввод из канала в сам цикл:
pipe=./diskfifo
while read word; do
[ "$word" = 'quit' ] && break
printf '%s\n' "$word"
done <"$pipe"
Это будет держать канал открытым на протяжении всего цикла. Каждый вызов read
будет наследовать свой стандартный входной поток от стандартного входа цикла, который подключен к каналу.
Возможная другая формулировка цикла:
while read word && [ "$word" != 'quit' ]; do
printf '%s\n' "$word"
done <"$pipe"