gnu paralelo: encaminha todo o stdin para todos os processos

gnu paralelo: encaminha todo o stdin para todos os processos

Estou tentando processar a entrada de diferentes maneiras em paralelo, escrevendo as linhas resultantes à medida que elas chegam. Minha abordagem atual é esta:

# process_parallel.sh
read input
parallel --colsep ' ' --linebuffer 'echo $input | {}' \
 ::: 'python process1.py' ./process2.sh ./process3

O contexto se resume a algo assim:

(sleep 1; echo "short input arriving late") | ./process_parallel.sh | ./collate_results.sh

O procedimento acima funciona, mas tem uma desvantagem importante: os processos não são iniciados até que a entrada seja lida. Quero iniciá-los imediatamente, pois isso pode demorar um pouco e, em seguida, colocar o canal paralelo em seu stdin completo para cada um deles.

Como faço para conseguir isso?

Responder1

Muito trabalho foi colocado no GNU Parallel para evitar que ele iniciasse um novo trabalho, a menos que houvesse dados para execução. Isso ocorre porque alguns programas falham muito se não receberem nenhuma entrada. Então você estará trabalhando contra o design do GNU Parallel.

Para duplicar a entrada você pode usar teee processar a substituição:

cat namedpipe_or_file | tee >(process1) >(process2) >(process3) >/dev/null

Ele começará process1, process2e process3imediatamente. A saída pode, no entanto, ser misturada, portanto, se a saída precisar ser usada, você deverá redirecioná-la para arquivos diferentes:

cat namedpipe_or_file | tee >(process1 > out1) >(process2 > out2) >(process3 > out3) >/dev/null

Responder2

Tenha dois scripts wrapper: primeiro, modifique process_parallel.sh para que cada um dos processos seja instruído a ler sua entrada, de três arquivos, digamos arquivo1, arquivo2, arquivo3.

Agora escreva um segundo script wrapper que envie paralelamente sua entrada padrão para os três arquivos, algo como:

  #!/bins/bash
  #parallelise input
  # let's call this file parallelise
  parallel -j 3 -- "echo $1 > file1" "echo $1 > file2" "echo $1 file3"

Agora você começa suas coisas com:

  ./process_parallel_sh; cat InputFile | parallelise; 

Responder3

Parallel tem uma --teeopção, que pode ser usada assim:

(sleep 1; echo "short input arriving late") |\
parallel --colsep ' ' --linebuffer --pipe --tee ::: 'python process1.py' ./process2.sh ./process3 |\
./collate_results.sh

VerGNU "paralelo" como alcançar o comportamento tee

informação relacionada