Por que meu comando paralelo imprime “Starting” e “Finished” ao mesmo tempo?

3
ls *.txt | parallel 'echo Starting on file {}; mkdir {.}; cd {.}; longCMD3 ../{} > /dev/null; echo Finished file {}'

Este forro parcial funciona parcialmente, exceto que longCMD3 leva cerca de 3 minutos, mas os primeiros e segundos comandos de eco são impressos quase ao mesmo tempo. Eu tentei colocar em

wait

antes do eco final, mas isso não fez diferença.

Como posso garantir que o eco final seja impresso apenas quando o longCMD3 estiver completo?

Veja um exemplo

Suponha que eu tenha apenas 4 núcleos:

ls
foo1.txt foo2.txt foo3.txt foo4.txt foo5.txt foo6.txt 

O que eu esperava:

Starting on file foo1.txt
Starting on file foo2.txt
Starting on file foo3.txt
Starting on file foo4.txt

então pelo menos 2 minutos devem passar por longCMD3 para terminar em um dos arquivos

Finished file foo1.txt
Starting on file foo5.txt

Mas o que obtenho é:

Starting on file foo1.txt
Finished file foo1.txt
Starting on file foo2.txt
Finished file foo2.txt
Starting on file foo3.txt
Finished file foo3.txt
Starting on file foo4.txt
Finished file foo4.txt

Isso continua para todos os 6 arquivos. E as instruções Start e Finished são impressas simultaneamente para cada arquivo. Mas alguns minutos são gastos entre cada arquivo.

    
por Glubbdrubb 29.12.2017 / 15:29

1 resposta

5

Para cada arquivo, os comandos echo Starting on file foo.txt , mkdir foo , cd foo , longCMD3 ../foo.txt > /dev/null e echo Finished file foo.txt são executados sequencialmente, ou seja, cada comando é iniciado depois que o anterior é concluído.

Os comandos para arquivos diferentes são intercalados. Por padrão, o comando paralelo executa tantos trabalhos em paralelo quanto os núcleos.

No entanto, a saída dos comandos não é intercalada por padrão. É por isso que você não vê muitas linhas "Iniciais" e depois as linhas "Concluídas" correspondentes. Grupos paralelos a saída de cada trabalho em conjunto. Ele armazena a saída até que o trabalho seja concluído. Veja a descrição da opção --group no manual. O agrupamento não faz sentido no seu caso, portanto, desative-o com a opção --ungroup ( -u ) ou mude para o agrupamento de linhas com --line-buffer .

Algumas outras correções:

  • A análise de ls não é confiável . Passe os nomes dos arquivos para parallel diretamente.
  • Se mkdir falhar, você não deve continuar. Se algum comando falhar, você deverá providenciar a falha do trabalho. Uma maneira fácil de fazer isso é iniciar o script do job com set -e .
parallel --line-buffer 'set -e; echo Starting on file {}; mkdir {.}; cd {.}; longCMD3 ../{} > /dev/null; echo Finished file {}' ::: *.txt
    
por 29.12.2017 / 17:00