Kernel Linux mengirimkan sinyal ke proses tentang peristiwa yang mereka perlukan untuk bereaksi. Skrip yang berperilaku baik menangani sinyal dengan elegan dan kuat dan dapat membersihkan di belakangnya sendiri bahkan jika Anda menekan Ctrl+C. Begini caranya.
Signals dan Processes
Signals adalah pesan satu arah yang singkat, cepat, dikirim ke proses seperti skrip, program, dan daemon. Mereka membiarkan proses tahu tentang sesuatu yang telah terjadi. Pengguna mungkin telah menekan Ctrl+C, atau aplikasi mungkin telah mencoba menulis ke memori yang tidak memiliki akses ke.
Jika pembuat proses telah mengantisipasi bahwa sinyal tertentu mungkin dikirim ke sana, mereka dapat menulis rutin ke dalam program atau skrip untuk menangani sinyal itu. Rutinitas seperti itu disebut penangan sinyal. Ini menangkap atau menjebak sinyal, dan melakukan beberapa tindakan sebagai tanggapannya.
Linux menggunakan banyak sinyal, seperti yang akan kita lihat, tetapi dari sudut pandang skrip, hanya ada sebagian kecil sinyal yang mungkin menarik bagi Anda. Khususnya, dalam skrip non-sepele, sinyal yang memberi tahu skrip untuk dimatikan harus dijebak (jika memungkinkan) dan pematian yang anggun dilakukan.
Misalnya, skrip yang membuat file sementara atau membuka port firewall dapat diberi kesempatan untuk menghapus file sementara atau menutup port sebelum dimatikan. Jika skrip mati begitu menerima sinyal, komputer Anda dapat dibiarkan dalam keadaan yang tidak terduga.
Berikut cara menangani sinyal dalam skrip Anda sendiri.
Signal
Beberapa perintah Linux memiliki nama samar. Tidak begitu perintah yang menjebak sinyal. Ini disebut perangkap. Kita juga dapat menggunakan trap dengan opsi -l (list) untuk menunjukkan kepada kita seluruh daftar sinyal yang digunakan Linux.
trap -l
Meskipun daftar bernomor kita berakhir pada 64, sebenarnya ada 62 sinyal. Sinyal 32 dan 33 hilang. Mereka tidak diimplementasikan di Linux. Mereka telah digantikan oleh fungsionalitas di kompiler gcc untuk menangani utas waktu nyata. Semuanya, mulai dari sinyal 34, SIGRTMIN, hingga sinyal 64, SIGRTMAX, adalah sinyal waktu nyata.
Anda akan melihat daftar yang berbeda pada sistem operasi mirip Unix yang berbeda. Di OpenIndiana misalnya, sinyal 32 dan 33 hadir, bersama dengan sekelompok sinyal tambahan yang membuat jumlah total menjadi 73.
Signals dapat dirujuk dengan nama, nomor, atau dengan nama singkatnya. Nama singkat mereka hanyalah nama mereka dengan "SIG" terkemuka dihapus.
Signals dinaikkan karena berbagai alasan. Jika Anda dapat menguraikannya, tujuan mereka terkandung dalam nama mereka. Dampak sinyal termasuk dalam salah satu dari beberapa kategori:
Terminate: Proses dihentikan.Abaikan: Sinyal tidak memengaruhi proses. Ini adalah sinyal informasi saja.Core: File dump-core dibuat. Hal ini biasanya dilakukan karena proses telah melanggar dalam beberapa cara, seperti pelanggaran memori.Stop: Proses dihentikan. Artinya, dijeda, tidak dihentikan.Lanjutkan: Memberi tahu proses yang dihentikan untuk melanjutkan eksekusi.
Ini adalah sinyal yang paling sering Anda temui.
- SIGHUP: Sinyal 1. Sambungan ke host jarak jauh—seperti server SSH—memiliki tiba-tiba terjatuh atau pengguna telah keluar. Skrip yang menerima sinyal ini mungkin berhenti dengan baik, atau mungkin memilih untuk mencoba menyambung kembali ke host jarak jauh.
- SIGINT: Sinyal 2. Pengguna telah menekan kombinasi Ctrl+C untuk memaksa proses ditutup, atau perintah kill telah digunakan dengan sinyal 2. Secara teknis, ini adalah sinyal interupsi, bukan sinyal terminasi, tetapi skrip yang terputus tanpa penangan sinyal biasanya akan berakhir.
- SIGQUIT: Sinyal 3. Pengguna telah menekan kombinasi Ctrl+D untuk memaksa proses berhenti, atau perintah kill telah digunakan dengan sinyal 3.
- SIGFPE: Sinyal 8. Proses mencoba melakukan operasi matematika ilegal (tidak mungkin), seperti pembagian dengan nol.
- SIGKILL: Sinyal 9. Ini adalah sinyal yang setara dengan guillotine. Anda tidak dapat menangkap atau mengabaikannya, dan itu terjadi secara instan. Proses segera dihentikan.
- SIGTERM: Sinyal 15. Ini adalah versi SIGKILL yang lebih perhatian. SIGTERM juga memberi tahu suatu proses untuk dihentikan, tetapi proses tersebut dapat terjebak dan proses tersebut dapat menjalankan proses pembersihannya sebelum ditutup. Ini memungkinkan shutdown yang anggun. Ini adalah sinyal default yang dibangkitkan oleh perintah kill.
Signal pada Command Line
Salah satu cara untuk menjebak sinyal adalah dengan menggunakan trap dengan nomor atau nama sinyal, dan respon yang diinginkan terjadi jika sinyal diterima. Kita dapat mendemonstrasikan ini di jendela terminal.
Perintah ini menjebak sinyal SIGINT. Responsnya adalah mencetak sebaris teks ke jendela terminal. Kami menggunakan opsi -e (enable escapes) dengan echo sehingga kami dapat menggunakan penentu format “n”.
trap `echo -e "+c Detected."` SIGINT
Baris teks kami dicetak setiap kali kami menekan Ctrl +C kombinasi.
Untuk melihat apakah jebakan dipasang pada sinyal, gunakan opsi -p (jebakan cetak).
trap -p SIGINT
Menggunakan jebakan tanpa opsi melakukan hal yang sama.
Untuk menyetel ulang sinyal ke keadaan normal yang tidak dijebak, gunakan tanda hubung “-” dan nama sinyal yang terperangkap.
trap - SIGINT
trap -p SIGINT
Tidak ada output dari perintah trap -p menunjukkan tidak ada perangkap yang dipasang pada sinyal itu.
Mencatat Signal dalam Skrip
Kita dapat menggunakan perintah trap format umum yang sama di dalam a naskah. Skrip ini menjebak tiga sinyal berbeda, SIGINT, SIGQUIT, dan SIGTERM.
#!/bin/bash trap "echo I was SIGINT dihentikan; exit" SIGINT trap "echo I was SIGQUIT dihentikan; exit" SIGQUIT trap "echo I was SIGTERM dihentikan ; exit" SIGTERM echo $$ counter=0 while true do echo "Nomor loop:" $((++counter)) sleep 1 done
Tiga pernyataan trap berada di bagian atas skrip. Perhatikan bahwa kami telah menyertakan perintah keluar di dalam respons untuk setiap sinyal. Ini berarti skrip bereaksi terhadap sinyal dan kemudian keluar.
Salin teks ke editor Anda dan simpan dalam file bernama “simple-loop.sh”, dan buat agar dapat dieksekusi menggunakan perintah chmod. Anda harus melakukannya untuk semua skrip dalam artikel ini jika Anda ingin mengikuti di komputer Anda sendiri. Cukup gunakan nama skrip yang sesuai di setiap case.
chmod +x simple-loop.sh
Skrip lainnya sangat sederhana. Kami perlu mengetahui ID proses skrip, jadi kami memiliki skrip yang menggemakannya kepada kami. Variabel $$ menyimpan ID proses skrip.
Kami membuat variabel yang disebut penghitung dan menyetelnya ke zero.
Perulangan while akan berjalan selamanya kecuali dihentikan secara paksa. Itu menambah variabel penghitung, menggemakannya ke layar, dan tidur sebentar.
Mari kita jalankan skrip dan kirim sinyal yang berbeda ke sana.
./simple-loop.sh
Ketika kita menekan "Ctrl+C" pesan kita dicetak ke jendela terminal dan skrip dihentikan.
Mari kita jalankan lagi dan kirim sinyal SIGQUIT menggunakan perintah kill. Kita harus melakukannya dari jendela terminal lain. Anda harus menggunakan ID proses yang dilaporkan oleh script.
./simple-loop.shkill Anda sendiri -SIGQUIT 4575
Seperti yang diharapkan, skrip melaporkan sinyal yang tiba kemudian berhenti. Dan akhirnya, untuk membuktikan maksudnya, kita akan melakukannya lagi dengan sinyal SIGTERM.
./simple-loop.shkill -SIGTERM 4584
Kami telah memverifikasi bahwa kami dapat menjebak banyak sinyal dalam sebuah skrip, dan bereaksi terhadap masing-masing sinyal secara independen. Langkah yang mempromosikan semua ini dari menarik menjadi bermanfaat adalah menambahkan penangan sinyal.
Menangani Sinyal di Skrip
Kita dapat mengganti string respons dengan nama fungsi di skrip Anda. Perintah trap kemudian memanggil fungsi tersebut ketika sinyal terdeteksi.
Salin teks ini ke dalam editor dan simpan sebagai file bernama “grace.sh”, dan buat itu dapat dieksekusi dengan chmod.
#!/bin/bash trap graceful_shutdown SIGINT SIGQUIT SIGTERM graceful_shutdown() { echo -e "nMenghapus file sementara:" $temp_file rm -rf "$temp_file" exit } temp_file=$(mktemp -p /tmp tmp.XXXXXXXXXX) echo "File temp yang dibuat:" $temp_file counter= 0 while true do echo "Loop number:" $((++counter)) sleep 1 done
Script menetapkan trap untuk tiga sinyal berbeda— SIGHUP, SIGINT, dan SIGTERM—menggunakan satu pernyataan trap. Responsnya adalah nama fungsi graceful_shutdown(). Fungsi ini dipanggil setiap kali salah satu dari tiga sinyal yang terperangkap diterima.
Script membuat file sementara di direktori “/tmp”, menggunakan mktemp. Template nama file adalah “tmp.XXXXXXXXXX”, jadi nama filenya adalah “tmp.” diikuti oleh sepuluh karakter alfanumerik acak. Nama file bergema di layar.
Skrip lainnya sama dengan yang sebelumnya, dengan variabel penghitung dan loop while tak terbatas.
./grace.sh
Ketika file dikirim, sinyal yang menyebabkannya tutup, fungsi graceful_shutdown() dipanggil. Ini menghapus file sementara tunggal kami. Dalam situasi dunia nyata, itu bisa melakukan pembersihan apa pun yang diperlukan skrip Anda.
Selain itu, kami menggabungkan semua sinyal yang terperangkap bersama-sama dan menanganinya dengan satu fungsi. Anda dapat menangkap sinyal satu per satu dan mengirimkannya ke fungsi pengendali khusus mereka sendiri.
Salin teks ini dan simpan dalam file bernama “triple.sh”, dan buat agar dapat dieksekusi menggunakan perintah chmod.
#!/bin/bash
trap "echo I was SIGINT terminated; exit" SIGINT
trap "echo I was SIGQUIT terminated; exit" SIGQUIT
trap "echo I was SIGTERM terminated; exit" SIGTERM
echo $$
counter=0
while true
do
echo "Loop number:" $((++counter))
sleep 1
done
Kami mendefinisikan tiga perangkap di bagian atas skrip.
One menjebak SIGINT dan memiliki pengendali yang disebut sigint_handler(). Yang kedua menangkap sinyal yang disebut SIGUSR1 dan menggunakan pengendali yang disebut sigusr1_handler() .Trap nomor tiga menjebak sinyal EXIT. Sinyal ini dimunculkan oleh skrip itu sendiri saat ditutup. Menyetel pengendali sinyal untuk EXIT berarti Anda dapat mengatur fungsi yang akan selalu dipanggil saat skrip dihentikan (kecuali jika dimatikan dengan sinyal SIGKILL). Handler kami disebut exit_handler() .
SIGUSR1 dan SIGUSR2 adalah sinyal yang disediakan sehingga Anda dapat mengirim sinyal khusus ke skrip Anda. Bagaimana Anda menafsirkan dan bereaksi terhadapnya sepenuhnya terserah Anda.
Kesampingkan penangan sinyal untuk saat ini, isi skrip seharusnya sudah tidak asing lagi bagi Anda. Ini menggemakan ID proses ke jendela terminal dan membuat beberapa variabel. Variabel sigusr1_count mencatat berapa kali SIGUSR1 ditangani, dan sigint_count mencatat berapa kali SIGINT ditangani. Variabel loop_flag disetel ke zero.
Perulangan while bukan perulangan tak berhingga. Ini akan berhenti mengulang jika variabel loop_flag disetel ke nilai bukan nol. Setiap putaran while loop menggunakan kill untuk mengirim sinyal SIGUSR1 ke skrip ini, dengan mengirimkannya ke ID proses skrip. Skrip dapat mengirim sinyal ke dirinya sendiri!
Fungsi sigusr1_handler() menambah variabel sigusr1_count dan mengirim pesan ke jendela terminal.
Setiap kali sinyal SIGINT diterima, fungsi siguint_handler() menambah variabel sigint_count dan menggemakan nilainya ke jendela terminal .
Jika variabel sigint_count sama dengan tiga, variabel loop_flag disetel ke satu dan sebuah pesan dikirim ke jendela terminal yang memberi tahu pengguna bahwa proses shutdown telah dimulai.
Karena loop_flag tidak lagi sama dengan nol, loop while berakhir dan skrip selesai. Tetapi tindakan itu secara otomatis meningkatkan sinyal EXIT dan fungsi exit_handler() dipanggil.
./triple.sh
Setelah tiga kali Ctrl+C ditekan, skrip berhenti dan secara otomatis memanggil fungsi exit_handler().
Membaca Signal
Dengan menjebak sinyal dan menanganinya dalam fungsi handler langsung, Anda dapat membuat skrip Bash Anda rapi di belakang mereka sendiri bahkan jika mereka tiba-tiba dihentikan. Itu memberi Anda sistem file yang lebih bersih. Ini juga mencegah ketidakstabilan saat Anda menjalankan skrip berikutnya, dan—tergantung pada tujuan skrip Anda—bahkan dapat mencegah lubang keamanan.
Itulah berita seputar
Cara Menggunakan Sinyal Linux di Skrip Bash, semoga bermanfaat.
Disadur dari HowToGeek.com.