Como eu fecho um pipe FIFO?

6

Este script:

#!/bin/bash
tmppipe=/tmp/temppipe
mkfifo $tmppipe
echo "test" > $tmppipe
cat $tmppipe
exit

Não finaliza. Eu suponho que o comando cat está esperando por um EOF do pipe; como faço para enviar um?

    
por Benubird 04.06.2015 / 11:27

2 respostas

7

Não, é

echo test > "$tmppipe" # BTW, you've got the quotes in the wrong places

que trava. Mais precisamente, é o shell abrindo o pipe para gravação antes de executar echo .

pipe são mecanismos de comunicação entre processos, eles devem ser usados entre processos em execução simultaneamente . Aqui, o open(WR_ONLY) ( > ) irá bloquear até que outro processo faça um open no modo de leitura.

echo test > "$tmppipe" &
cat < "$tmppipe"

funcionará porque echo e cat são executados simultaneamente.

No Linux, você pode se safar:

exec 3<> "$tmppipe"
echo test >&3
cat < "$tmppipe"
exec 3<&-

Isso funciona porque ler + escrever open s ( <> ) em pipes não são bloqueados no Linux, e porque a test\n output por echo é pequena o suficiente para caber no pipe, então você pode faça a gravação e a leitura sequencialmente.

Não funcionaria para uma produção maior como:

exec 3<> "$tmppipe"
seq 100000 >&3
cat < "$tmppipe"
exec 3<&-

Porque seq preencheria o pipe (64kiB nas versões atuais do Linux) e bloquearia até algum outro processo ler dados desse pipe, o que nunca acontecerá porque cat não será executado até que seq tenha terminado .

Observe que:

echo test 1<> "$tmppipe"
cat < "$tmppipe"

também não funcionaria porque a linha de comando echo abriria o pipe, escreveria o teste e fecharia o pipe (e o sistema o destruiria, já que não há mais descritor de arquivo aberto). Portanto, a próxima linha de comando cat tentaria instanciar um novo canal (e bloquear até que algo abra o arquivo fifo para gravação).

    
por 05.06.2015 / 12:21
0

Acontece que a resposta é óbvia - o pipe está sendo bloqueado por echo e nunca chega ao gato!

Os pipes não armazenam dados. Quando um processo tenta gravar em um pipe, a gravação não pode ser concluída até que haja algo anexado à outra extremidade do pipe, para lê-lo.

Uma maneira de resolver esse exemplo específico é usar

echo "test" > $tmppipe &

para fazer com que o processo de escrita seja executado em segundo plano. Dessa forma, fica lá aguarda, enquanto o script continua, até atingir o cat e poder completar.

    
por 05.06.2015 / 12:12

Tags