Estou tentando escrever um arquivo .sh que executa muitos programas simultaneamente
Eu tentei isso
prog1
prog2
Mas isso executa prog1, então espera até que prog1 termine e, em seguida, inicia prog2 ...
Então, como posso executá-los em paralelo?
bash
parallel-processing
Betamoo
fonte
fonte
wait
! Sim, no bash você pode esperar pelos processos filhos do script.nohup
para impedir que o programa seja morto quando o shell desligar.E se:
Isso vai:
prog1
.prog2
e mantenha-o em primeiro plano , para que você possa fechá-loctrl-c
.prog2
, você vai voltar paraprog1
's primeiro plano , então você também pode fechá-lo comctrl-c
.fonte
prog1
quandoprog2
termina? Pense emnode srv.js & cucumberjs
prog1 & prog2 ; fg
Isso era para executar vários túneis ssh de uma só vez. Espero que isso ajude alguém.prog2
não funcionar imediatamente, você voltará a ficarprog1
em primeiro plano. Se isso é desejável, está tudo bem.prog1 & prog2 && kill $!
.Você pode usar
wait
:Ele atribui os PIDs do programa em segundo plano às variáveis (
$!
é o último PID do processo iniciado) e owait
comando as espera. É legal porque se você matar o script, ele também matará os processos!fonte
#!/usr/bin/env bash ARRAY='cat bat rat' for ARR in $ARRAY do ./run_script1 $ARR & done P1=$! wait $P1 echo "INFO: Execution of all background processes in the for loop has completed.."
${}
para interpolá-lo em uma lista de seqüências de caracteres ou similar.Com o GNU Parallel http://www.gnu.org/software/parallel/ , é tão fácil quanto:
Ou se você preferir:
Saber mais:
fonte
parallel
diferentes com sintaxe diferente. Por exemplo, nos derivativos Debian, omoreutils
pacote contém um comando diferente chamadoparallel
que se comporta de maneira bem diferente.parallel
melhor do que usar&
?parallel
é melhor quando há mais trabalhos que núcleos; nesse caso,&
seria executado mais de um trabalho por núcleo de uma só vez. (cf. princípio pigeonhole )Se você deseja executar e matar com facilidade vários processos com facilidade
ctrl-c
, este é o meu método favorito: gerar vários processos em segundo plano em um(…)
subshell e fazer uma armadilhaSIGINT
para executarkill 0
, o que matará tudo o que for gerado no grupo de subshells:Você pode ter estruturas complexas de execução de processos, e tudo será fechado com uma única
ctrl-c
(apenas verifique se o último processo é executado em primeiro plano, ou seja, não inclua um&
depoisprog1.3
):fonte
xargs -P <n>
permite executar<n>
comandos em paralelo.Embora
-P
seja uma opção não padrão, as implementações GNU (Linux) e macOS / BSD a suportam.O exemplo a seguir:
A saída se parece com:
O tempo mostra que os comandos foram executados em paralelo (o último comando foi iniciado somente após o término do primeiro dos 3 originais, mas executado muito rapidamente).
O
xargs
comando em si não retornará até que todos os comandos tenham sido concluídos, mas você pode executá-lo em segundo plano encerrando-o com o operador de controle&
e, em seguida, usando owait
builtin para aguardarxargs
a conclusão de todo o comando.Nota:
O BSD / macOS
xargs
exige que você especifique a contagem de comandos a serem executados em paralelo explicitamente , enquanto o GNUxargs
permite especificar-P 0
a execução do maior número possível em paralelo.A saída dos processos executados em paralelo chega à medida que está sendo gerada , portanto será imprevisivelmente intercalada .
parallel
, como mencionado na resposta de Ole (não é padrão na maioria das plataformas), serializa (agrupa) convenientemente a saída por processo e oferece muitos recursos mais avançados.fonte
Redirecionar erros para separar logs.
fonte
prog1 2> .errorprog1.log & prog2 2> .errorprog2.log &
ls notthere1 & 2> .errorprog1.log; ls notthere2 & 2>.errorprog2.log
. Os erros vão para o console e os dois arquivos de erro estão vazios. Como @Dennis Williamson diz,&
é um separador, assim;
, (a) ele precisa ir no final do comando (após qualquer redirecionamento) e (b) você não precisa de;
nada :-)Existe um programa muito útil que chama nohup.
fonte
nohup
por si só não executa nada em segundo plano, e o usonohup
não é um requisito ou pré-requisito para executar tarefas em segundo plano. Eles geralmente são úteis juntos, mas, como tal, isso não responde à pergunta.Aqui está uma função que eu uso para executar no máximo n processo em paralelo (n = 4 no exemplo):
Se max_children estiver definido como o número de núcleos, essa função tentará evitar núcleos inativos.
fonte
wait -n
requerbash
4.3+ e muda a lógica para aguardar o término de qualquer um dos processos especificados / implícitos.Você pode tentar ppss . ppss é bastante poderoso - você pode até criar um mini-cluster. O xargs -P também pode ser útil se você tiver um lote de processamento paralelamente embaraçoso para fazer.
fonte
Recentemente, tive uma situação semelhante em que precisava executar vários programas ao mesmo tempo, redirecionar suas saídas para arquivos de log separados e esperar que eles terminassem, e acabei com algo assim:
Fonte: http://joaoperibeiro.com/execute-multiple-programs-and-redirect-their-outputs-linux/
fonte
Gerente de Geração de Processos
Certamente, tecnicamente, esses são processos, e esse programa deve realmente ser chamado de gerenciador de criação de processos, mas isso se deve apenas à maneira como o BASH funciona quando bifurca usando o e comercial, usa a chamada de sistema fork () ou talvez clone () que clona em um espaço de memória separado, em vez de algo como pthread_create () que compartilharia memória. Se o BASH suportasse o último, cada "sequência de execução" funcionaria da mesma forma e poderia ser denominada como threads tradicionais, enquanto ganhava uma pegada de memória mais eficiente. No entanto, funcionalmente, funciona da mesma maneira, embora um pouco mais difícil, pois as variáveis GLOBAL não estão disponíveis em cada clone do trabalhador, portanto, o uso do arquivo de comunicação entre processos e o semáforo rudimentar do rebanho para gerenciar seções críticas. Bifurcação do BASH, é claro, é a resposta básica aqui, mas sinto que as pessoas sabem disso, mas realmente querem gerenciar o que é gerado, em vez de apenas bifurcar e esquecê-lo. Isso demonstra uma maneira de gerenciar até 200 instâncias de processos bifurcados, acessando um único recurso. Claramente, isso é um exagero, mas eu gostei de escrever, então continuei. Aumente o tamanho do seu terminal de acordo. Espero que você ache isso útil.
fonte
Seu script deve se parecer com:
Supondo que seu sistema possa executar n trabalhos por vez. use wait para executar apenas n trabalhos por vez.
fonte
Com o bashj ( https://sourceforge.net/projects/bashj/ ), você deve poder executar não apenas vários processos (da maneira que outros sugeriram), mas também vários Threads em uma JVM controlada a partir do seu script. Mas é claro que isso requer um JDK java. Threads consomem menos recursos que processos.
Aqui está um código de trabalho:
fonte