Por que o redirecionamento de arquivo de e para um pipe nomeado não funciona, mas a canalização para o gato funciona?

8

Este é um servidor de eco simples no Unix, usando nc:

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

(com base nisso )

Como posso ver, o fluxo de dados funciona da seguinte maneira:

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

E aqui está a pergunta: por que isso não funciona?

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

Você vai notar que se você tentar telnetpara localhostem 4458que você vai ter um "Conexão recusada" erro.

Razvan
fonte
Não tenho uma resposta, mas espero que isso ajude alguém mais experiente que eu. cat myfifo | nc -k -l 4458 > myfifotambém funciona. Se você usar um arquivo de texto, file.txt assim: nc -k -l 4458 < file.txt > file.txtA primeira conexão será conectada e fechada (faz sentido porque a entrada foi truncada e o EOF fecha o soquete), a segunda conexão se tornará um servidor de eco esquecido: ecoará em todas as outras linhas e salve as linhas não especificadas no arquivo de texto.
User1794469

Respostas:

9

Isso ocorre porque o comando netcat ainda nem foi iniciado! O shell ao tentar abrir o fifo para entrada será bloqueado. Tentar

strace cat >fifo <fifo

e você não verá nada. Em vez disso, use, por exemplo,

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

que abre o fifo para leitura e gravação como stdin e, em seguida, copia para stdout.


O rastreamento do comando bash completo mostra que nem a abertura para leitura nem gravação retorna (até que a abertura oposta seja concluída):

$ 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: Abrir um FIFO para leitura normalmente bloqueia até que outro processo abra o mesmo FIFO para gravação e vice-versa.

meuh
fonte
1
O bloqueio está documentado: tldp.org/LDP/lpg/node19.html
thrig
Por que o shell bloqueia ao usar "> fifo <fifo"? Parece que o abre para escrever e depois para ler. Portanto, como já existe um identificador para escrever aberto, ele não deve continuar normalmente?
Razvan
@Razvan Atualizei a resposta com o rastreio real das duas ordens alternativas de abertura do fifo, e você pode vê-lo aberto para escrever ou ler os dois blocos.
meuh 19/05/16