У меня есть программа, которая автоматически выходит при чтении EOF в данном потоке (в следующем случае, stdin).
Теперь я хочу создать сценарий оболочки, который создает именованный канал и подключает к нему stdin программы. Затем скрипт записывает в канал несколько раз, используя echo
и cat
(и другие инструменты, которые автоматически генерируют EOF при выходе). Проблема, с которой я сталкиваюсь, заключается в том, что, когда первое echo
сделано, оно отправляет EOF в канал и завершает работу программы. Если я использую что-то вроде tail -f
этого, я не могу отправить EOF, когда я собираюсь выйти из программы. Я исследую сбалансированное решение, но безрезультатно.
Я уже нашел, как предотвратить EOF и как вручную отправить EOF, но я не могу объединить их. Есть ли подсказка?
#!/bin/sh
mkfifo P
program < P & : # Run in background
# < P tail -n +1 -f | program
echo some stuff > P # Prevent EOF?
cat more_stuff.txt > P # Prevent EOF?
send_eof > P # How can I do this?
# fg
exec 3>P
причина зависания в bash, почему?exec 2>P
, и у вас включен режим трассировки (set -x
), в котором bash собирается записывать в канал, но читателя нет, поэтому он блокирует ожидание что-то почитать.exec 3>P
На моей машине тоже висит bash. Это потому, что нет процесса чтения изP
. Таким образом, решением было поменять строкиexec 3>P
иprogram < P &
(добавив амперсанд так, чтобы программа работала в фоновом режиме).Труба получает EOF, когда последний писатель уходит. Чтобы избежать этого, убедитесь, что всегда есть писатель (процесс, у которого канал открыт для записи, но на самом деле ничего не пишет). Чтобы отправить EOF, заставьте этого резервного автора уйти.
источник
У программы нет возможности провести различие между EOF, который означает «пришло время выходить», и EOF, который означает «автор завершен, но может быть больше информации от кого-то другого».
Если у вас есть возможность изменить поведение вашей программы, выполните чтение в бесконечном цикле (одна итерация длится до EOF) и отправьте ей специальную командную строку, которая означает «время для выхода». Отправка этой строки будет задачей
send_eof
команды в вашем вопросе.Другой вариант:
или
источник