Eseguire un comando bash dopo alcuni comandi simultanei?


13

Voglio eseguire alcuni comandi in parallelo. Al termine di tutti questi comandi, avvia il successivo. Penso che il seguente approccio funzionerà

#!/bin/bash
command1 &
command2 &
command3 &&
command4

ma non lo fece. Devo eseguire command4quando tutti i primi tre comandi sono stati completamente completati.

Risposte:


28
#!/bin/bash
command1 &
command2 &
command3 &

wait
command4

wait (senza alcun argomento) attenderà fino alla chiusura di tutti i processi in background.

La descrizione completa di waitnel bashmanuale:

wait [-n] [n ...]

Attendere ogni processo figlio specificato e restituire lo stato di terminazione. Ciascuno npuò essere un ID processo o una specifica del lavoro; se viene fornita una specifica lavoro, tutti i processi nella pipeline di quel lavoro sono attesi. Se nnon viene fornito, tutti i processi figlio attualmente attivi sono attesi e lo stato di ritorno è zero. Se -nviene fornita l' opzione, waitattende la conclusione di qualsiasi processo e restituisce il suo stato di uscita. Se nspecifica un processo o processo inesistente, lo stato di restituzione è 127. In caso contrario, lo stato di restituzione è lo stato di uscita dell'ultimo processo o processo atteso.


1
Un'altra opzione è quella di salvare il PID di ogni bambino utilizzando qualcosa di simile PID1=$!e quindi attendere tutti con wait "$PID1" "$PID2" "$PID3". Questo è leggermente più complicato, ma funzionerà se il processo ha altri figli che non vuoi aspettare.
Kasperd,

1
@kasperd Meglio con un array in quel caso: cmd1 & pids=( $! ); cmd2 & pids+=( $! ); cmd3 & pids+=( $! ); wait "${pids[@]}"o qualcosa di simile.
Kusalananda

@kasperd Per "meglio" intendo "usa solo una variabile". Niente di intrinsecamente sbagliato nell'uso di molti, ed è probabilmente del tutto ok per casi come questo.
Kusalananda

0

Mi piace la waitrisposta, ma proprio come un esercizio accademico, penso che funzionerebbe anche:

bash -c 'command1 & command2 & command3 &' && command4

Perfavore, correggimi se sbaglio.


2
Hai provato questo? Non funziona assolutamente. Esempio: time bash -c "sleep 5 &sleep 5 &sleep 5 &" && echo foo se non dice che il comando bash ha impiegato cinque secondi, non ha fatto quello che volevi.
Seth Robertson,

L'ho provato con il sonno e gli echi e sembrava funzionare. Il tuo esempio dimostra il contrario.
hamburger,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.