O processo é encerrado inesperadamente ao enviar para um pipe nomeado

O processo é encerrado inesperadamente ao enviar para um pipe nomeado

Eu tenho dois processos e um pipe nomeado.

Um processo está lendo ativamente do canal e outro processo está enviando dados para o canal continuamente.

O comando que envia para o pipe é o seguinte:

sudo iotop -b -P > diskfifo

O leitor, por outro lado, está simplesmente executando uma operação de leitura em loop no tubo

pipe=./diskfifo

while read line <$pipe
do
    if [[ "$line" == 'quit' ]]; then
        break
    fi
    echo $line
done

Problema: o comando iotop às vezes para após um certo número de iterações e não consigo entender o porquê.

Porém, notei que se eu reduzir a quantidade de dados enviados o comando iotop não para.

Responder1

Em cada iteração do seu loop, readabrirá o pipe para leitura, lerá uma linha de dados e depois fechará.

Se iotopdecidir tentar escrever no pipe enquanto readnão estiver lendo ativamente dele, ele receberá um PIPEsinal, pois tenta escrever em um pipe do qual ninguém está lendo. A ação padrão ao receber o PIPEsinal é encerrar o processo.

Em vez de abrir e fechar o pipe para leitura no loop (e esperar que isso iotopnão escreva no pipe enquanto ele não estiver sendo lido), redirecione a entrada do pipe para o próprio loop:

pipe=./diskfifo

while read word; do
    [ "$word" = 'quit' ] && break
    printf '%s\n' "$word"
done <"$pipe"

Isso manteria o tubo aberto durante toda a duração do loop. Cada invocação readherdaria seu fluxo de entrada padrão da entrada padrão do loop, que está conectado ao tubo.


Uma possível outra formulação do loop:

while read word && [ "$word" != 'quit' ]; do
    printf '%s\n' "$word"
done <"$pipe"

informação relacionada