Saya memiliki skrip bash sederhana yang menjalankan dua server:
#!/bin/bash
(cd ./frontend && gulp serve) & (cd ./backend && gulp serve --verbose)
Jika perintah kedua keluar, sepertinya perintah pertama terus berjalan.
Bagaimana saya bisa mengubah ini sehingga jika salah satu perintah keluar, yang lain dihentikan?
Perhatikan bahwa kita tidak perlu memeriksa tingkat kesalahan dari proses latar belakang, hanya apakah sudah keluar.
bash
shell-script
background-process
blah238
sumber
sumber
gulp ./fronend/serve && gulp ./backend/serve --verbose
?serve
adalah argumen, bukan file, jadi direktori saat ini perlu diatur.Jawaban:
Ini memulai kedua proses, menunggu yang pertama selesai dan kemudian membunuh yang lain:
Bagaimana itu bekerja
Mulailah:
Dua perintah di atas memulai kedua proses di latar belakang.
Tunggu
Ini menunggu pekerjaan latar belakang untuk berakhir.
Karena
-n
opsi, ini membutuhkan bash 4.3 atau lebih baik.Membunuh
Ini membunuh pekerjaan apa pun yang prosesnya saat ini adalah induknya. Dengan kata lain, ini membunuh semua proses latar belakang yang masih berjalan.
Jika sistem Anda tidak memiliki
pkill
, coba ganti baris ini dengan:yang juga membunuh grup proses saat ini .
Contoh mudah diuji
Dengan mengubah skrip, kami dapat mengujinya bahkan tanpa
gulp
diinstal:Script di atas dapat dijalankan sebagai
bash script.sh 1 3
dan proses pertama berakhir terlebih dahulu. Atau, seseorang dapat menjalankannyabash script.sh 3 1
dan proses kedua akan berakhir terlebih dahulu. Dalam kedua kasus, orang dapat melihat bahwa ini beroperasi seperti yang diinginkan.sumber
bash
mendukung-n
opsi untukwait
perintah. (2) Saya setuju 100% dengan kalimat pertama - solusi Anda memulai dua proses, menunggu yang pertama selesai dan kemudian membunuh yang lain. Tetapi pertanyaannya mengatakan "... jika salah satu perintah keluar , yang lain dihentikan?" Saya percaya bahwa solusi Anda bukanlah yang diinginkan OP. (3) Mengapa Anda mengubah(…) &
ke{ …; } &
? The&
pasukan daftar (perintah kelompok) untuk menjalankan dalam subkulit pula. IMHO, Anda telah menambahkan karakter dan mungkin menimbulkan kebingungan (saya harus melihatnya dua kali untuk memahaminya) tanpa manfaat.pkill
tidak tersedia untuk saya tetapikill 0
tampaknya memiliki efek yang sama. Saya juga memperbarui Git saya untuk lingkungan Windows dan sepertinyawait -n
berfungsi sekarang, jadi saya menerima jawaban ini.kill
. dokumentasi pada sistem saya tidak menyebutkannya. Namun,kill 0
tetap bekerja. Bagus temukan!Ini rumit. Inilah yang saya rancang; dimungkinkan untuk menyederhanakan / merampingkannya:
while true; do sleep 42; done &
) yang tidur / berhenti selamanya. Jika Anda yakin bahwa dua perintah Anda akan berakhir dalam jangka waktu tertentu (misalnya, satu jam), Anda dapat mengubahnya ke satu tidur yang akan melebihi itu (misalnya,sleep 3600
). Anda kemudian dapat mengubah logika berikut untuk menggunakan ini sebagai batas waktu; yaitu, bunuh proses jika mereka masih berjalan setelah banyak waktu. (Perhatikan bahwa skrip di atas saat ini tidak melakukan itu.)./
melakukannyacd
.command & echo "$!" > somewhere; wait "$!"
adalah konstruksi rumit yang memulai proses secara tidak sinkron, menangkap PID-nya, dan kemudian menunggu; menjadikannya semacam proses foreground (sinkron). Tapi ini terjadi dalam(…)
daftar yang berada di latar belakang secara keseluruhan, sehinggagulp
prosesnya berjalan secara tidak sinkron.gulp
proses keluar, tulis statusnya ke file sementara dan matikan proses "sleep selamanya".sleep 1
untuk melindungi terhadap kondisi balapan di mana proses latar belakang pertama mati sebelum yang kedua mendapat kesempatan untuk menulis PID-nya ke file.gulp
proses keluar, seperti yang dinyatakan di atas.sumber
Untuk kelengkapan, inilah yang akhirnya saya gunakan:
Ini berfungsi untuk saya di Git untuk Windows 2.5.3 64-bit. Versi yang lebih lama mungkin tidak menerima
-n
opsi aktifwait
.sumber
Di sistem saya (Centos),
wait
tidak-n
jadi saya melakukan ini:Ini tidak menunggu "baik", melainkan menunggu yang pertama. Tetapi tetap bisa membantu jika Anda tahu server mana yang akan dihentikan terlebih dahulu.
sumber
wait
memiliki-n
opsi atau tidak tergantung pada shell yang Anda gunakan, bukan distribusi Linux.