De acordo com a lista de discussão do GNU Parallel, este não é um problema específico do GNU Parallel. Eles sugeriram que eu postasse meu problema aqui.
O erro que estou recebendo é um erro de "tubo quebrado", mas sinto que devo primeiro explicar o contexto do meu problema e o que causa esse erro. Isso acontece ao tentar usar qualquer script bash contendo um loop 'while read' no GNU Parallel.
Eu tenho um script bash básico como este:
#!/bin/bash
# linkcheck.sh
while read domain
do
host "$domain"
done
Suponha que eu queira criar uma lista grande (digamos, 250 MB).
cat urllist | ./linkcheck.sh
Executar o comando host em URLs de 250 MB é bastante lento. Para acelerar as coisas, quero dividir a entrada em partes antes de canalizá-la e, em seguida, executar vários trabalhos em paralelo. GNU Parallel é capaz de fazer isso.
cat urllist | parallel --pipe -j0 parallel ./linkcheck.sh {}
{} é substituído pelo conteúdo de urllist linha por linha. Suponha que a configuração padrão do meu sistema seja capaz de executar 500 trabalhos por instância paralela. Para contornar essa limitação, podemos paralelizar o próprio Parallel:
cat urllist | parallel -j10 --pipe parallel -j0 ./linkcheck.sh {}
Isso executará 5.000 empregos. Infelizmente, também causará o erro "tubo quebrado"(perguntas frequentes sobre bash). No entanto, o script começa a funcionar se eu remover o loop while read e receber a entrada diretamente de tudo o que é inserido em {}, por exemplo,
#!/bin/bash
# linkchecker.sh
domain="$1"
host "$1"
Por que não funcionará com um loop while read? É seguro simplesmente desligar o sinal SIGPIPE para interromper a mensagem de "tubo quebrado" ou isso terá efeitos colaterais, como corrupção de dados?
Obrigado por ler.
Responder1
Assim o fez
lista de URLs de gatos | paralelo --pipe -j0 paralelo ./linkcheck.sh {}
funciona corretamente? Acredito que parte do seu problema pode ser que você deixou de fora o segundo --pipe
, como em
lista de URLs de gatos | paralelo -j10 --pipe paralelo -j0--cano./linkcheck.sh {}
Aliás, você nunca precisa dizer
gatoarquivo_um|algum_comando
Você sempre pode mudar isso para
algum_comando<arquivo_um
resultando em um processo a menos (e um tubo a menos). (Pode ser apropriado/necessário usar cat
quando você tiver vários arquivos de entrada.)
Responder2
Parece-me que o erro pode estar surgindo devido a uma condição de corrida ruim devido à janela entre bifurcar um filho para executar outra cópia de linkcheck.sh enquanto o canal ainda está aberto e quando o filho realmente tenta ler. Nessa janela, outra cópia leu EOF e o canal foi fechado.