Почему не работает перенаправление файлов в и из именованного канала, а работает конвейер в cat?

8

Это простой эхо-сервер в Unix, использующий nc:

mkfifo fifo
cat fifo | nc -k -l 4458 -v | cat >fifo

(основываясь на этом )

Насколько я понимаю, поток данных работает следующим образом:

fifo (my named pipe)
 |
 | (using cat)
 |
 v
nc
 |
 | (using cat)
 |
 v
fifo 

И вот вопрос: почему это не работает?

nc -k -l 4458 -v >fifo <fifo

Вы заметите , что если вы пытаетесь , telnetчтобы localhostна 4458вы получите «Connection отказался» сообщение об ошибке.

Разван
источник
У меня нет ответа, но, надеюсь, это поможет кому-то более знающему, чем я. cat myfifo | nc -k -l 4458 > myfifoтоже работает. Если вы используете текстовый файл, file.txt как и nc -k -l 4458 < file.txt > file.txtпервое соединение будет подключаться и близко (имеет смысл , так как вход был усечен и EOF закрывает сокет), то второе соединение будет забывчивый сервер эхо: оно отзовется любой другой линии и сохраните unchoed строки в текстовый файл.
user1794469

Ответы:

9

Это потому, что команда netcat еще даже не запущена! Оболочка при попытке открыть fifo для ввода заблокируется. Пытаться

strace cat >fifo <fifo

и ты ничего не увидишь. Вместо этого используйте, например,

nc -k -l 4458 -v <>fifo >&0

который открывает fifo для чтения и записи как stdin, а затем переводит его в стандартный вывод.


Трассировка команды full bash показывает, что ни open для чтения, ни запись не возвращаются (пока не будет выполнено противоположное открытие):

$ strace -f -e open bash -c 'nc -k -l 4458 -v  >fifo <fifo'
...
Process 3631 attached
[pid  3631] open("fifo", O_WRONLY|O_CREAT|O_TRUNC, 0666

$ strace -f -e open bash -c 'nc -k -l 4458 -v  <fifo >fifo'
...
Process 3684 attached
[pid  3684] open("fifo", O_RDONLY

man 3 mkfifo: Открытие FIFO для обычного чтения блоков, пока какой-то другой процесс не откроет тот же FIFO для записи, и наоборот.

meuh
источник
1
Блокирующий документирована: tldp.org/LDP/lpg/node19.html
thrig
Почему оболочка блокируется при использовании "> fifo <fifo"? Казалось бы, он открывает его для записи, а затем для чтения. Итак, поскольку уже открыт дескриптор для записи, разве он не должен продолжаться нормально?
Разван
@Razvan Я обновил ответ с фактической страной для двух альтернативных ордеров открытия fifo, и вы можете увидеть, что открыт для записи или чтения обоих блоков.
Мех