Настройка чтения конвейеров из именованных каналов без блокировки в bash
Вопрос
Я ищу, чтобы вызвать подпроцесс с дескриптором файла, открытым для данного канала, чтобы вызов open () не зависал, ожидая, пока другая сторона канала не получит соединение.
Для демонстрации:
$ mkfifo /tmp/foobar.pipe
$ some_program --command-fd=5 5</tmp/foobar.pipe
В этом случае some_program
не запускается до тех пор, пока какой-либо процесс не откроет /tmp/foobar.pipe
для записи; однако O_NONBLOCK
имеет полезные эффекты даже тогда, когда не получает команды, поэтому желаемое поведение должно выполняться <=> немедленно.
Механизмы, позволяющие сделать это, используя альтернативный язык сценариев (python, perl и т. д.) или оболочку C, открывающую <=> с флагом <=>, очевидны; Я ищу решение для чистого bash, если это возможно.
Решение
Открытие FD для чтения / записи, а не только для чтения, при настройке конвейера предотвращает блокировку.
Чтобы быть немного более конкретным:
$ mkfifo /tmp/foobar.pipe
$ some_program --command-fd=5 5<>/tmp/foobar.pipe
предотвращает нежелательное поведение блокировки, так как 5<>/tmp/foobar.pipe
открывается в режиме RW (в отличие от открытия в режиме только для чтения, как при 5</tmp/foobar.pipe
), хотя O_NONBLOCK
все еще установлен. Спасибо Waldner на irc: //irc.freenode.org/#bash за этот указатель.
Другие советы
Единственный способ получить такой результат - это взлом:
mkfifo /tmp/foobar.in
mkfifo /tmp/foobar.out
( cat </tmp/foobar.in ) >/tmp/foobar.out &
some_program --command-fd=5 5</tmp/foobar.out
возможно это поможет: -)