GNU/Linux >> Belajar Linux >  >> Linux

Bash:tunggu dengan batas waktu

Contoh Anda dan jawaban yang diterima terlalu rumit, mengapa Anda tidak hanya gunakan timeout karena itu persis kasus penggunaannya? timeout perintah bahkan memiliki opsi bawaan (-k ) untuk mengirim SIGKILL setelah mengirimkan sinyal awal untuk mengakhiri perintah (SIGTERM secara default) jika perintah masih berjalan setelah mengirimkan sinyal awal (lihat man timeout ).

Jika skrip tidak perlu wait dan melanjutkan alur kontrol setelah menunggu, itu hanya masalah

timeout -k 60s 60s app1 &
timeout -k 60s 60s app2 &
# [...]

Namun, jika ya, itu sama mudahnya dengan menyimpan timeout PID sebagai gantinya:

pids=()
timeout -k 60s 60s app1 &
pids+=($!)
timeout -k 60s 60s app2 &
pids+=($!)
wait "${pids[@]}"
# [...]

Mis.

$ cat t.sh
#!/bin/bash

echo "$(date +%H:%M:%S): start"
pids=()
timeout 10 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 1 terminated successfully"' &
pids+=($!)
timeout 2 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 2 terminated successfully"' &
pids+=($!)
wait "${pids[@]}"
echo "$(date +%H:%M:%S): done waiting. both jobs terminated on their own or via timeout; resuming script"

.

$ ./t.sh
08:59:42: start
08:59:47: job 1 terminated successfully
08:59:47: done waiting. both jobs terminated on their own or via timeout; resuming script

Tulis PID ke file dan jalankan aplikasi seperti ini:

pidFile=...
( app ; rm $pidFile ; ) &
pid=$!
echo $pid > $pidFile
( sleep 60 ; if [[ -e $pidFile ]]; then killChildrenOf $pid ; fi ; ) &
killerPid=$!

wait $pid
kill $killerPid

Itu akan membuat proses lain yang tidur selama waktu tunggu dan mematikan proses jika belum selesai sejauh ini.

Jika proses selesai lebih cepat, file PID dihapus dan proses pembunuh dihentikan.

killChildrenOf adalah skrip yang mengambil semua proses dan mematikan semua turunan dari PID tertentu. Lihat jawaban pertanyaan ini untuk berbagai cara mengimplementasikan fungsi ini:Cara terbaik untuk menghentikan semua proses anak

Jika Anda ingin keluar dari BASH, Anda dapat menulis PID dan batas waktu ke direktori dan menonton direktori itu. Setiap menit atau lebih, baca entri dan periksa proses mana yang masih berjalan dan apakah waktunya habis.

EDIT Jika Anda ingin mengetahui apakah proses telah berhasil mati, Anda dapat menggunakan kill -0 $pid

EDIT2 Atau Anda dapat mencoba memproses grup. kevinarpe berkata:Untuk mendapatkan PGID untuk PID(146322):

ps -fjww -p 146322 | tail -n 1 | awk '{ print $4 }'

Dalam kasus saya:145974. Kemudian PGID dapat digunakan dengan opsi khusus kill untuk menghentikan semua proses dalam grup:kill -- -145974


Linux
  1. Bash Array Dengan Contoh

  2. Pernyataan Bash If-Else Dengan Contoh

  3. Waitpid setara dengan batas waktu?

  1. Bash -c Dengan Parameter Posisi?

  2. Apa yang poll() lakukan dengan batas waktu 0?

  3. Alias ​​​​dengan variabel di bash

  1. nama dasar dengan spasi dalam skrip bash?

  2. Menambahkan stempel waktu ke nama file dengan mv di BASH

  3. Linux Bash XMLLINT dengan XPATH