Настройка конвейеров, считывающих данные из именованных каналов без блокировки в bash

#bash #unix #shell #pipe

Вопрос:

Я ищу, чтобы вызвать подпроцесс с файловым дескриптором, открытым для данного канала, таким образом, чтобы вызов open() не зависал в ожидании, пока другая сторона канала получит соединение.

Чтобы продемонстрировать:

 $ mkfifo /tmp/foobar.pipe
$ some_program --command-fd=5 5</tmp/foobar.pipe
 

В этом случае some_program он не запускается до тех пор, пока какой-либо процесс не /tmp/foobar.pipe откроется для записи; однако some_program он имеет полезные эффекты, даже если он не получает команд, поэтому желаемое поведение some_program должно быть немедленно выполнено.

Механизмы для этого, выполняемые с помощью альтернативного языка сценариев (python, perl и т. Д.) Или оболочки C, Которые открываются /tmp/foobar.pipe с O_NONBLOCK флагом, очевидны; Я ищу решение для чистого bash, если оно возможно.

Ответ №1:

Открытие 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 все еще задано. Спасибо Вальднеру в irc://irc.freenode.org/#bash за этот указатель.

Ответ №2:

Единственный известный мне способ получить такой результат-это взломать:

 mkfifo /tmp/foobar.in
mkfifo /tmp/foobar.out
( cat </tmp/foobar.in ) >/tmp/foobar.out amp;
some_program --command-fd=5 5</tmp/foobar.out
 

возможно, это поможет 🙂

Комментарии:

1. вы правы, это была опечатка. просто отредактировал его. И да, фоновый процесс уродлив, вот почему я назвал его взломом 🙂