Perintah GNU coreutils timeout
sangat berguna untuk situasi scripting tertentu, memungkinkan untuk menggunakan output dari sebuah perintah jika itu cepat dijalankan, dan melewatkannya jika itu akan memakan waktu terlalu lama.
Bagaimana saya bisa memperkirakan perilaku dasar timeout
menggunakan hanya utilitas yang ditentukan POSIX?
(Aku berpikir itu mungkin melibatkan kombinasi wait
, sleep
, kill
dan siapa tahu apa lagi, tapi mungkin aku kehilangan pendekatan yang lebih mudah.)
shell-script
posix
timeout
Wildcard
sumber
sumber
command & pid=$! ; sleep 5 && kill $pid
command
selesai dengan cepat ada kemungkinan tipis yangpid
akan digunakan kembali oleh proses lain memulai sebelumkill
perintah dijalankan? Saya tidak ingin itu dalam kode produksi ....timeout
program saja dan menggunakannya?Jawaban:
Pendekatan saya adalah yang ini:
Menjalankan perintah sebagai proses latar belakang 1
Jalankan "pengawas waktu" sebagai proses latar belakang 2
Siapkan pawang untuk menjebak sinyal terminasi di kulit induk
Tunggu hingga kedua proses selesai. Proses yang berakhir terlebih dahulu, mengirimkan sinyal terminasi ke induk.
Penangan perangkap orang tua membunuh kedua proses latar belakang melalui kontrol pekerjaan (salah satu dari mereka telah diakhiri secara definisi, tetapi pembunuhan itu akan menjadi larangan yang tidak berbahaya karena kita tidak menggunakan PID, lihat di bawah)
Saya mencoba untuk menghindari kemungkinan kondisi ras yang dibahas dalam komentar dengan menggunakan ID kontrol pekerjaan shell (yang akan jelas dalam contoh shell ini) untuk mengidentifikasi proses latar belakang untuk membunuh, bukan PID sistem.
Hasil untuk
TIMEOUT=10
(perintah berakhir sebelum pengawas):Hasil untuk
TIMEOUT=1
(watchdog berakhir sebelum perintah):Hasil untuk
TIMEOUT=5
(anjing pengawas dan perintah menghentikan "hampir" secara bersamaan):sumber
cleanup() { ...; }
dan (b) kontrol pekerjaan adalah fitur bash yang tidak ditentukan oleh POSIX (meskipun ksh dan yang lainnya juga memilikinya). Skrip yang bagus!timeout="$1"; shift
dan(exec "$@"; echo "Command completed"; kill $$)
bukannya mengulangi kata-kata daftar argumen.