Ver "Tubo quebrado" nessa situação é raro, mas normal.
Quando você executa type rvm | head -1
, o bash é executado type rvm
em um processo, head -1
em outro. 1 O stdout de type
está conectado à extremidade "write" de um pipe , o stdout da extremidade head
"read". Ambos os processos são executados ao mesmo tempo.
O head -1
processo lê os dados do stdin (geralmente em pedaços de 8 kB), imprime uma única linha (de acordo com a -1
opção) e sai, fazendo com que a extremidade "lida" do tubo seja fechada. Como a rvm
função é bastante longa (cerca de 11 kB após ser analisada e reconstruída pelo bash), isso significa que head
sai enquanto type
ainda há alguns kB de dados para gravar.
Neste ponto, como type
está tentando gravar em um pipe cuja outra extremidade foi fechada - um pipe quebrado - a função write () que ele chamou retornará um erro EPIPE, traduzido como "Pipe quebrado". Além desse erro, o kernel também envia o sinal SIGPIPE para type
, que por padrão mata o processo imediatamente.
(O sinal é muito útil em shells interativos, pois a maioria dos usuários não deseja que o primeiro processo continue em execução e tente gravar em lugar nenhum. Enquanto isso, serviços não interativos ignoram o SIGPIPE - não seria bom para um daemon de longa execução morrem com um erro tão simples - para que eles achem o código de erro muito útil.)
No entanto, a entrega do sinal não é 100% imediata e pode haver casos em que write () retorne o EPIPE e o processo continue em execução por um curto período de tempo antes de receber o sinal. Nesse caso, type
obtém tempo suficiente para observar a falha na gravação, traduzir o código de erro e até imprimir uma mensagem de erro no stderr antes de ser morto pelo SIGPIPE. (A mensagem de erro diz "-bash: type:", pois type
é um comando interno do próprio bash.)
Isso parece ser mais comum em sistemas com várias CPUs, pois o type
processo e o código de entrega de sinal do kernel podem ser executados em núcleos diferentes, literalmente ao mesmo tempo.
Seria possível remover esta mensagem type
corrigindo o código interno (no código-fonte do bash) para sair imediatamente quando receber um EPIPE da função write ().
No entanto, não há com o que se preocupar e não está relacionado à sua rvm
instalação de forma alguma.
ls
meiohead -1
por anos, e hoje eu estou recebendo uma mensagem de tubulação quebrada.Você pode consertar um tubo quebrado às custas de outro processo , inserindo
tail -n +1
-o, assim:O
+1
diztail
para imprimir a primeira linha de entrada e tudo o que se segue. A saída será exatamente igual à quetail -n +1
não existia, mas o programa é inteligente o suficiente para verificar a saída padrão e fechar o tubo de maneira limpa. Chega de canos quebrados .fonte
find /var/lib/mysql -xdev -type f -daystart -mmin +5 -print0 | xargs -0 ls -ldt | tail -n +1 | head
produz de forma confiávelxargs: ls: terminated by signal 13
. Como sabemos, o problema é de exaustão de entrada e há realmente apenas um comando que lida com o buffer: dd. A adição| dd obs=1M
ao pipeline corrige o SIGPIPE para o meu caso de uso.type rvm | (head -1 ; dd of=/dev/null)
Isto, naturalmente, é semelhante a outras sugestões, uma vez que está causando toda a entrada a ser processado , masdd
deve ser o programa mais eficiente para lidar com essas coisas.A
write error: Broken pipe
mensagem refere-se a um processo de gravação que tenta gravar em um canal sem nenhum leitor deixado na extremidade de leitura desse canal e a circunstância especial de que oSIGPIPE
sinal está configurado para ser ignorado pelo processo atual ou pelo processo pai. Se foi o processo pai que configurouSIGPIPE
para ser ignorado, não é possível que o processo filho desfaça isso novamente em um shell não interativo.No entanto, é possível eliminar
type rvm
quandohead -1
termina usando subcascas explícitas. Dessa forma, podemos fazer o segundo planotype rvm
, enviartypepid
para ohead -1
subshell e implementar uma armadilhaEXIT
para matartype rvm
explicitamente.fonte
type
obtém tempo suficiente para observar a falha na gravação, traduzir o código de erro e até imprimir uma mensagem de erro no stderr antes de ser morto pelo SIGPIPE . Acho que sua solução não impede que o processo produtor (type
aqui) reaja à falha na gravação (devido ao tubo fechado), não é?