Como posso saber se a gravação em um pipe nomeado seria bloqueada?

4

Eu quero escrever para um pipe nomeado somente se ele já tiver um leitor. Atualmente, estou usando timeout para detectar se a tentativa de gravar no pipe foi bloqueada da seguinte forma:

#! /usr/bin/env bash
rm -f pipe
mkfifo pipe
sleep 5

timeout 1 bash -c "echo Hello > pipe"

if [[ $? == 0 ]]
then
    echo Somebody got our message
else
    echo Nobody read from pipe, so we didn\'t send a message
fi

Isso funciona. Se eu tail -f pipe em um terminal separado durante o sono eu recebo uma mensagem, e se não, recebo a outra. Mas há um caminho melhor? Idealmente, seria algo que não dependesse de um tempo limite.

    
por MatrixManAtYrService 07.10.2018 / 19:01

1 resposta

4

Se você quiser gravar no pipe, somente se houver algum processo que o tenha aberto para leitura, você poderá abri-lo para escrever no modo sem bloqueio.

Com o GNU dd :

echo Hello | dd oflag=nonblock of=pipe status=none &&
  echo message has been sent

E você receberá a mensagem de erro do ENXIO (algo como Nenhum dispositivo ou endereço em inglês) se não houver um leitor.

Observe que ele também falharia (com EWOULDBLOCK / EAGAIN , Recurso temporariamente indisponível ) se o canal estiver cheio (se houver um leitor, mas não estiver lendo no momento e algo como 64KiB já foram escritos para ele).

Observe também que nem toda a mensagem pode ser escrita se não couber. Se você remover o status=none , verá o quanto foi escrito.

    
por 08.10.2018 / 16:12

Tags