Jalankan perintah bash setelah beberapa perintah simultan?

13

Saya ingin menjalankan beberapa perintah secara paralel. Ketika semua perintah ini selesai, mulailah yang berikutnya. Saya pikir pendekatan berikut ini akan berhasil

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

tapi ternyata tidak. Saya perlu menjalankan command4ketika semua tiga perintah pertama telah selesai.

Googlebot
sumber

Jawaban:

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

wait
command4

wait (tanpa argumen) akan menunggu sampai semua proses latar belakang telah keluar.

Deskripsi lengkap waitdalam bashmanual:

wait [-n] [n ...]

Tunggu setiap proses anak yang ditentukan dan kembalikan status penghentiannya. Masing n- masing dapat berupa ID proses atau spesifikasi pekerjaan; jika spec pekerjaan diberikan, semua proses dalam pipeline pekerjaan menunggu. Jika ntidak diberikan, semua proses anak yang sedang aktif menunggu, dan status pengembalian adalah nol. Jika -nopsi ini disediakan, waittunggu pekerjaan apa pun untuk berakhir dan mengembalikan status keluarnya. Jika nmenentukan proses atau pekerjaan yang tidak ada, status pengembalian adalah 127. Jika tidak, status pengembalian adalah status keluar dari proses terakhir atau pekerjaan yang ditunggu.

Kusalananda
sumber
1
Pilihan lain adalah menyimpan PID setiap anak menggunakan sesuatu seperti PID1=$!dan kemudian menunggu mereka semua wait "$PID1" "$PID2" "$PID3". Itu sedikit lebih rumit, tetapi akan berhasil jika proses tersebut memiliki anak-anak lain yang Anda tidak ingin menunggu.
kasperd
1
@kasperd Lebih baik dengan array dalam hal ini: cmd1 & pids=( $! ); cmd2 & pids+=( $! ); cmd3 & pids+=( $! ); wait "${pids[@]}"atau sesuatu yang serupa.
Kusalananda
@kasperd Dengan "lebih baik" Maksudku "hanya menggunakan satu variabel". Tidak ada yang salah dengan menggunakan banyak, dan mungkin benar-benar baik untuk kasus-kasus kecil seperti ini.
Kusalananda
0

Saya suka waitjawabannya, tetapi hanya sebagai latihan akademis, saya pikir ini juga akan berhasil:

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

Tolong koreksi saya jika saya salah.

burger
sumber
2
Apakah Anda menguji ini? Sama sekali tidak bekerja. Contoh: time bash -c "sleep 5 &sleep 5 &sleep 5 &" && echo foo Jika tidak mengatakan perintah bash membutuhkan waktu lima detik, itu tidak melakukan apa yang Anda inginkan.
Seth Robertson
Saya mengujinya dengan tidur dan gema dan sepertinya berhasil. Contoh Anda membuktikan sebaliknya.
burger