Como executar grupos de comandos em paralelo?

4

Estou tentando executar grupos de comandos em paralelo. Existem 10 grupos e cada grupo tem 3 comandos. Eu quero execução sequencial dentro de cada grupo e execução paralela dos 10 grupos. Eu estou tentando algo assim, mas isso não parece funcionar:

(command11; command12; command13 &)
(command21; command22; command23 &)
(command31; command32; command33 &)
(command41; command42; command43 &)
...
    
por user3769454 17.08.2017 / 15:47

2 respostas

5

Com o GNU Parallel , seria:

parallel 'command{}1; command{}2; command{}3' ::: {1..4}

ou se preferir substituição de comandos :

parallel 'command{}1; command{}2; command{}3' ::: $(seq 4)

O GNU Parallel tem cerca de 150 opções de controle de trabalho que você pode querer estudar, mas comece com o tutorial em vídeo .

    
por 17.08.2017 / 17:48
3

Como você deseja

Quase atingido. A sintaxe correta é:

(command11; command12; command13) &
(command21; command22; command23) &
(command31; command32; command33) &
(command41; command42; command43) &

Como quiser, mas melhor

Ou, se você quiser que dentro de um grupo os comandos sejam omitidos após um comando falhar, a sintaxe é

command11 && command12 && command13 &
command21 && command22 && command23 &
command31 && command32 && command33 &
command41 && command42 && command43 &

Nota: " && " tem um significado muito diferente como " & ". " && " significa que o comando será executado somente depois que o anterior estiver pronto e somente se ele foi executado sem uma falha (ou seja, seu código de saída é zero). " & " significa que o comando antes dele será executado em paralelo com a linha de execução principal, e sua falha ou sucesso não importa.

Usando a ferramenta xargs

No entanto, essas soluções têm a desvantagem de que você não pode esperar após todos desses comandos serem executados. Para fazer isso, temos um pouco mais de truques. Especialmente no seu caso, o comando necessário para fazer isso seria

for i in 1 2 3 4 5 6 7 8 9 10
do
  echo "command${i}1 && command${i}2 && command${i}3"
done | xargs -P 10 -l 1 bash -c

Ele usa a ferramenta muito útil xargs . É claro que você pode canalizar qualquer coisa para ele, por exemplo, se você quiser processar milhares de coisas em 10 segmentos paralelos, ele fará.

Funciona de uma forma, que chama o comando bash -c para todas as linhas de entrada, paralelas , mas que, no máximo, 10 processos filhos serão coincidentemente executados (isso é feito por o código%). O comando -P 10 termina apenas se todos os processos do bash foram executados.

Ferramenta paralela (veja outras respostas)

O GNU também escreveu uma ferramenta chamada xargs . Até onde eu sei, sua sintaxe é um pouco mais clara a partir do parallel s, embora tenha menos recursos e não seja tão comum. Provavelmente outras respostas explicarão isso.

Módulo "paralelo" NodeJs

Se você está trabalhando na estrutura nodejs , também há uma ferramenta muito comumente usada ( xargs ), que é usada principalmente para paralelizar tarefas de construção automatizadas, mas também pode ser usada em shellscripts facilmente.

Não é uma boa idéia em ambientes comuns, porque npm install parallel packages não se integra muito bem com o ambiente de manipulação de pacotes Unix. Embora sua sintaxe seja muito mais fácil, seus recursos estão muito atrás de todas as outras soluções.

No caso de seu problema específico, eu provavelmente escolheria a segunda solução em um caso simples, e a solução baseada em xargs em uma solução mais complexa.

    
por 17.08.2017 / 16:00