Executar um comando bash após alguns comandos simultâneos?
13
Eu quero executar alguns comandos em paralelo. Quando todos esses comandos estiverem concluídos, inicie o próximo. Embora a seguinte abordagem funcione
wait (sem argumentos) aguardará até que todos os processos em segundo plano sejam encerrados.
A descrição completa waitdo bashmanual:
wait [-n] [n ...]
Aguarde cada processo filho especificado e retorne seu status de encerramento. Cada um npode ser um ID de processo ou uma especificação de trabalho; se uma especificação de trabalho for fornecida, todos os processos no pipeline desse trabalho serão aguardados. Se nnão for fornecido, todos os processos filhos ativos no momento são aguardados e o status de retorno é zero. Se a
-nopção for fornecida, waitaguarde o término de qualquer trabalho e retorne seu status de saída. Se nespecificar um processo ou trabalho inexistente, o status de retorno será 127. Caso contrário, o status de retorno será o status de saída do último processo ou trabalho aguardado.
Outra opção é salvar o PID de cada criança usando algo como PID1=$!e, em seguida, esperar por todas elas wait "$PID1" "$PID2" "$PID3". Isso é um pouco mais complicado, mas funcionará se o processo tiver outros filhos pelos quais você não deseja esperar.
Kasperd #
1
@ Kasperd Melhor com uma matriz nesse caso: cmd1 & pids=( $! ); cmd2 & pids+=( $! ); cmd3 & pids+=( $! ); wait "${pids[@]}"ou algo semelhante.
Kusalananda
@kasperd Por "melhor", quero dizer "usa apenas uma variável". Nada inerentemente errado com o uso de muitos, e provavelmente é totalmente aceitável para casos pequenos como este.
Kusalananda
0
Eu gosto da waitresposta, mas apenas como um exercício acadêmico, acho que isso também funcionaria:
Você testou isso? Absolutamente não funciona. Exemplo: time bash -c "sleep 5 &sleep 5 &sleep 5 &" && echo foo se ele não disser que o comando bash levou cinco segundos, não fez o que você deseja.
Seth Robertson
Eu testei com sono e ecos e parecia funcionar. Seu exemplo prova o contrário.
PID1=$!
e, em seguida, esperar por todas elaswait "$PID1" "$PID2" "$PID3"
. Isso é um pouco mais complicado, mas funcionará se o processo tiver outros filhos pelos quais você não deseja esperar.cmd1 & pids=( $! ); cmd2 & pids+=( $! ); cmd3 & pids+=( $! ); wait "${pids[@]}"
ou algo semelhante.Eu gosto da
wait
resposta, mas apenas como um exercício acadêmico, acho que isso também funcionaria:Por favor corrija-me se eu estiver errado.
fonte
time bash -c "sleep 5 &sleep 5 &sleep 5 &" && echo foo
se ele não disser que o comando bash levou cinco segundos, não fez o que você deseja.