Setiap kill %1 dan setiap Ctrl+C yang kita pakai sejauh ini sebenarnya mengirimkan hal yang sama: sinyal — pesan pendek bernomor dari kernel kepada sebuah proses, yang bisa berarti “berhenti”, “berhenti sementara”, atau “lanjutkan”. Nama perintah kill menyesatkan — tugas aslinya mengirim sinyal apa pun ke proses mana pun. Chapter ini membedah sinyal yang paling sering dipakai, konvensi exit status 128 + nomor sinyal, penangkapan sinyal dengan trap, serta alat penghenti massal pkill dan kerabatnya.
Sinyal: Pesan Asinkron dari Kernel #
Sinyal tidak masuk lewat antrean perintah program — ia menyela kapan saja di antara dua instruksi yang sedang dijalankan proses. Begitu tiba, proses menanggapi menurut disposition bawaannya: berhenti, berhenti sementara, diabaikan, atau ditangani handler miliknya. Sebagian besar sinyal bisa ditangkap dan diganti perilakunya; dua pengecualian mutlak adalah SIGKILL dan SIGSTOP — keduanya dikerjakan kernel tanpa pernah sampai ke proses. Tabel berikut merangkum yang paling sering kita jumpai:
| Nama | Nomor | Pemicu umum | Perilaku bawaan |
|---|---|---|---|
| SIGHUP | 1 | terminal terputus, logout | proses berhenti |
| SIGINT | 2 | Ctrl+C | proses berhenti |
| SIGQUIT | 3 | Ctrl+\ | proses berhenti + core dump |
| SIGKILL | 9 | kill -9 | berhenti seketika, tak bisa ditangkap |
| SIGTERM | 15 | kill tanpa opsi | proses berhenti, bisa ditangkap |
| SIGCONT | 18 | bg, fg | proses berhenti sementara dilanjutkan |
| SIGSTOP | 19 | Ctrl+Z | berhenti sementara, tak bisa ditangkap |
SIGINT adalah sinyal yang kita kirim setiap hari lewat Ctrl+C. Karena ini interaksi papan tombol di shell interaktif, berikut contoh tampilan sesinya, bukan output terverifikasi:
budi@laptop-budi:~$ sleep 600
^C
budi@laptop-budi:~$
Driver terminal mengubah Ctrl+C menjadi SIGINT untuk proses foreground, sleep mati tanpa kata pamit, dan prompt kembali. Nomor-nomor pada tabel di atas adalah versi arsitektur x86; daftar lengkap untuk mesin kita ada di halaman manual signal(7)
.
kill: Mengirim Sinyal, Bukan Membunuh #
Tanpa argumen sinyal, kill memilih SIGTERM — permintaan berhenti yang santun karena masih bisa ditangkap program. Proses yang mati karena sinyal meninggalkan jejak pada exit status: shell melaporkannya sebagai 128 + nomor sinyal. Mari kita buktikan ketiganya sekaligus:
sleep 5 & pid=$!
kill -INT $pid
wait $pid
echo "SIGINT = exit $?"
sleep 5 & pid=$!
kill $pid
wait $pid
echo "SIGTERM = exit $?"
sleep 5 & pid=$!
kill -9 $pid
wait $pid
echo "SIGKILL = exit $?"Output yang Dihasilkan:
SIGINT = exit 130
SIGTERM = exit 143
SIGKILL = exit 137Mari kita telaah blok di atas:
- Baris 1-4 (
sleep 5 &,kill -INT,wait,echo): proses latar dihentikan dengan SIGINT (nomor 2), laluwaitmengambil statusnya:130= 128 + 2. - Baris 5-8 (
killtanpa opsi): SIGTERM (15) menghasilkan143= 128 + 15 — angka yang sudah kita jumpai pada Chapter Foreground dan Background Processes . - Baris 9-12 (
kill -9): SIGKILL (9) menghasilkan137= 128 + 9. Job latar yang mati karena SIGKILL dilaporkan bash dengan barisKilleddi layar — di stdout blok ini ia tidak muncul.
Nama atau Nomor dengan kill -l #
Tiga cara penulisan sinyal setara: kill -9 1234, kill -KILL 1234, dan kill -s KILL 1234. Penerjemahnya adalah builtin kill -l: dari nomor ke nama bila diberi angka, dan sebaliknya:
for nomor in 1 2 9 15; do
printf 'SIG%-7s = sinyal nomor %d\n' "$(kill -l $nomor)" "$nomor"
done
echo "---"
kill -l TERM
kill -l KILLOutput yang Dihasilkan:
SIGHUP = sinyal nomor 1
SIGINT = sinyal nomor 2
SIGKILL = sinyal nomor 9
SIGTERM = sinyal nomor 15
---
15
9Mari kita telaah blok di atas:
- Baris 1-3 (
for nomor in ...): untuk empat nomor sinyal,kill -l $nomormenerjemahkannya menjadi nama, laluprintfmerapikan kolomnya —%-7smeratakan nama ke kiri selebar tujuh karakter. - Baris 5-6 (
kill -l TERMdankill -l KILL): arah sebaliknya — nama menjadi nomor; berguna saat menemukan angka seperti-15di dokumentasi dan ingin tahu sinyal apa yang dimaksud.
Tanpa argumen, kill -l mencetak seluruh daftar sinyal yang dikenal shell; sintaks lengkapnya ada di halaman manual kill(1)
.
Menangkap Sinyal dengan trap #
Karena SIGTERM bisa ditangkap, program yang santun menggunakannya sebagai momen perapihan: menutup file, memutus koneksi database, lalu keluar. Di skrip bash, handler dipasang dengan trap 'aksi' NAMA-SINYAL. Skrip berikut menolak mati tanpa pamit:
cat > penjaga.sh << 'EOF'
#!/bin/bash
trap 'echo "penjaga menerima sinyal TERM dan berhenti dengan rapi"; exit 0' TERM
while true; do sleep 1; done
EOF
chmod +x penjaga.sh
./penjaga.sh & pid=$!
sleep 0.5
kill -TERM $pid
wait $pid
echo "setelah SIGTERM: exit $?"
./penjaga.sh & pid=$!
sleep 0.5
kill -KILL $pid
wait $pid
echo "setelah SIGKILL: exit $?"Output yang Dihasilkan:
penjaga menerima sinyal TERM dan berhenti dengan rapi
setelah SIGTERM: exit 0
setelah SIGKILL: exit 137Mari kita telaah blok di atas:
- Baris 1-5 (heredoc
penjaga.sh): skrip berisi loopsleep 1tanpa henti; satu-satunya pintu keluarnya adalah trap yang mencetak pesan laluexit 0saat SIGTERM tiba — penundaan hingga satu detik itu wajar, karena bash menyelesaikan perintah yang sedang berjalan lebih dulu. - Baris 6-11 (
./penjaga.sh &,kill -TERM,wait): handler bekerja — pesan tercetak dan proses berhenti dengan status0, bukan143, karena kematiannya kini disengaja skrip sendiri. - Baris 12-16 (
kill -KILLlaluwait): SIGKILL tidak pernah sampai ke trap — skrip mati seketika dengan status137tanpa mencetak apa pun.
Menghentikan Berdasarkan Nama: pgrep dan pkill #
Menyalin PID dari ps satu per satu melelahkan untuk pekerjaan berulang. Pasangan pgrep dan pkill bekerja atas nama proses: pgrep mencarinya, pkill mengirim sinyal ke semua yang cocok sekaligus. Opsi -x meminta kecocokan persis pada nama proses — berikut dua worker kecil yang kita hentikan sekaligus:
printf '#!/bin/bash\nsleep 5\n' > pdemo.sh
chmod +x pdemo.sh
./pdemo.sh & a=$!
./pdemo.sh & b=$!
sleep 0.3
echo "pgrep menemukan $(pgrep -xc pdemo.sh) proses pdemo.sh"
pkill -x pdemo.sh
wait $a; echo "pdemo.sh pertama berhenti dengan exit $?"
wait $b; echo "pdemo.sh kedua berhenti dengan exit $?"Output yang Dihasilkan:
pgrep menemukan 2 proses pdemo.sh
pdemo.sh pertama berhenti dengan exit 143
pdemo.sh kedua berhenti dengan exit 143Mari kita telaah blok di atas:
- Baris 1-4: skrip kecil
pdemo.shdijalankan dua kali di background — dua proses bernama sama, persis pola pekerjaan seperti worker pool. - Baris 5-7 (
sleep 0.3,pgrep -xc,pkill -x): setelah jeda agar kedua proses pasti hidup,pgrep -xcmenghitung proses bernama persispdemo.sh, lalupkill -xmengirim SIGTERM ke keduanya sekaligus. - Baris 8-9 (
wait $adanwait $b): keduawaitmemanen status143masing-masing — bukti keduanya tumbang oleh sinyal yang sama.
Varian -f mencocokkan seluruh baris perintah, bukan hanya nama programnya — berguna untuk skrip berargumen panjang, tetapi berbahaya karena polanya bisa cocok dengan proses yang tak kita duga, termasuk shell yang sedang menjalankan perintah berisi kata itu. Kerabat dekatnya killall nama dari paket psmisc mengirim sinyal ke semua proses bernama persis nama; program itu tidak terpasang di lingkungan minimal buku ini tetapi tersedia di Debian dan Ubuntu, dan perilakunya terdokumentasi di halaman manual killall(1)
serta pgrep(1)
.
Kini kita bisa melahirkan proses di latar, menahannya, dan mengakhirinya dengan tingkat kesantunan yang kita pilih. Pertanyaan berikutnya soal keadilan: ketika ratusan proses berebut CPU, siapa yang berhak kebagian porsi lebih besar? Jawabannya ada pada nice value dan scheduler — materi Chapter Process Priority .