Yang Anda amati adalah bug dalam versi bash ini.
kill -9 %1
tidak membunuh pekerjaan itu segera. Anda dapat mengamati itu dengan ps
. Anda dapat melacak proses bash untuk melihat kapan kill
panggilan sistem dipanggil, dan melacak subproses untuk melihat kapan ia menerima dan memproses sinyal. Lebih menarik lagi, Anda dapat pergi dan melihat apa yang terjadi pada proses.
bash-4.3$ sleep 9999
^Z
[1]+ Stopped sleep 9999
bash-4.3$ kill -9 %1
[1]+ Stopped sleep 9999
bash-4.3$ jobs
[1]+ Stopped sleep 9999
bash-4.3$ jobs -l
[1]+ 3083 Stopped sleep 9999
bash-4.3$
Di terminal lain:
% ps 3083
PID TTY STAT TIME COMMAND
3083 pts/4 Z 0:00 [sleep] <defunct>
Subproses adalah zombie . Sudah mati: yang tersisa hanyalah entri dalam tabel proses (tetapi tidak ada memori, kode, buka file, dll.). Entri dibiarkan sampai induknya memperhatikan dan mengambil status keluar dengan memanggil wait
panggilan sistem atau salah satu saudara kandungnya .
Shell interaktif seharusnya memeriksa anak-anak yang mati dan menuai mereka sebelum mencetak prompt (kecuali jika dikonfigurasi sebaliknya). Versi bash ini gagal melakukannya dalam beberapa keadaan:
bash-4.3$ jobs -l
[1]+ 3083 Stopped sleep 9999
bash-4.3$ true
bash-4.3$ /bin/true
[1]+ Killed sleep 9999
Anda mungkin mengharapkan bash untuk melaporkan "Dibunuh" segera setelah mencetak prompt setelah kill
perintah, tetapi itu tidak dijamin, karena ada kondisi balapan. Sinyal dikirimkan secara tidak sinkron: kill
panggilan sistem kembali segera setelah kernel menentukan proses pengiriman sinyal, tanpa menunggu pengirimannya. Mungkin saja, dan dalam praktiknya, bash mempunyai waktu untuk memeriksa status subprosesnya, menemukan bahwa itu masih belum mati ( wait4
tidak melaporkan kematian anak), dan mencetak bahwa prosesnya masih dihentikan. Apa yang salah adalah bahwa sebelum prompt berikutnya, sinyal telah dikirim ( ps
melaporkan bahwa prosesnya mati), namun bash masih belum memanggilwait4
(kita bisa melihat itu bukan hanya karena masih melaporkan pekerjaan sebagai "Berhenti", tetapi karena zombie masih ada di tabel proses). Bahkan, bash hanya menuai zombie saat berikutnya perlu memanggil wait4
, ketika menjalankan beberapa perintah eksternal lainnya.
Bugnya berselang dan saya tidak bisa mereproduksinya saat bash dilacak (mungkin karena ini adalah kondisi balapan di mana bash perlu bereaksi cepat). Jika sinyal dikirim sebelum bash memeriksa, semuanya terjadi seperti yang diharapkan.