bash: Lendo um registro completo de um fifo

0

Eu desejo enviar um comando para processar A, do processo B, via FIFO.

O comando será uma palavra ou sentença, mas totalmente contido em uma linha terminada "\ n" - mas poderia, em geral, ser um registro de várias linhas, terminado por outro caractere.

A parte relevante do código que eu tentei, é algo assim:

Processo A:

$ mkfifo ff
$ read x < ff

Processo B: (a partir de outra janela do terminal)

$ echo -n "cmd"   > ff
$ echo -n " arg1" > ff
$ echo -n " arg2" > ff
 ...    
$ echo    " argN" > ff

No entanto, o que está acontecendo é que read retorna com o valor cmd , embora a página bash man diga que, por padrão, lê \n linhas terminadas, a menos que a opção -d delim seja usada .

Então, eu tentei especificar -d delim explicitamente,

$ read -d "\n" x < f'

e ainda o mesmo resultado.

Poderia echo -n estar fechando o arquivo descritor do FIFO?

Estou usando o bash 4.4.x no Ubuntu 18.04.

    
por Harry 11.06.2018 / 15:49

1 resposta

4

Sim, é exatamente o que acontece:

$ mkfifo p
$ while :; do cat p ; done > /dev/null  & 
$ strace -etrace=open,close bash -c 'echo -n foo > p; echo bar > p' |& grep '"p"' -A1
open("p", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(3)                                = 0
--
open("p", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(3)                                = 0

Os redirecionamentos só entram em vigor pela duração do comando único em que estão configurados. A solução alternativa no lado da escrita é a) usar um bloco composto para agrupar os comandos, ou b) usar exec para abrir um descritor de arquivo pela duração de todo o script (ou até fechado).

a)

{ echo -n foo; echo bar; } > p

(Você também pode colocar os comandos em uma função e usar o redirecionamento ao chamar a função.)

b)

exec 3>p
echo -n foo >&3
echo bar    >&3
exec 3>&-         # to explicitly close it

Se você quiser corrigi-lo no lado da leitura, será necessário executar um loop por read e concatenar as strings obtidas. Como você deseja explicitamente as não-linhas parciais e ignora as condições de fim de arquivo, não é possível usar o código de saída de read para algo útil.

    
por 11.06.2018 / 16:07

Tags