Como sair cedo no fechamento do tubo?

3

Eu uso o golang para escrever programas que são muito complexos para expressar como funções bash. Os programas leem stdin linha por linha e escrevem a saída modificada para stdout.

O problema com essa iteração em todas as linhas na abordagem stdin é que ela não sai mais cedo. Por exemplo, o comando a seguir processará todas as linhas em vez de apenas 10:

cat largefile | custom-program | head -n 10

Como o aplicativo unix nativo consegue sair antes e como posso fazer o mesmo em meus scripts personalizados?

    
por Kshitiz Sharma 13.11.2017 / 15:43

1 resposta

8

Em yes | head , yes é finalizado por um sinal SIGPIPE na próxima vez que gravar uma linha depois que a outra extremidade do canal for fechada (quando head sair).

Em:

(seq 20; sleep 10; seq 10) | head

O subshell e os filhos poderão gravar as primeiras 20 linhas no pipe (conforme elas se encaixam no buffer do pipe), e então dormirão 10 segundos sem danos. Enquanto isso, head terá morrido, mas é somente quando a subshell escreve mais linhas para o pipe que ele será morto.

Se você quiser que seu comando seja eliminado assim que head retornar, ao contrário da primeira vez em que ele escreve algo no pipe depois que head retornou, com bash você poderia fazer:

{ head; kill "$!"; } < <(exec custom-program < large-file)

( bash , por acaso, armazena o pid de substituição de processo em $! ).

Veja também Grep lento para sair depois de encontrar correspondência? para uma abordagem mais portátil ou limite localiza saída E evita sinal 13 para um aplicado a find .

Ou para o inverso esta resposta ( run_under_watch function) para um Q & A semelhante para eliminar um processo assim que o seu stdin torna-se um cano quebrado.

    
por 13.11.2017 / 15:59