คำตอบโดย @hvd นั้นถูกต้องแล้ว ในการสำรองข้อมูลให้มากขึ้นinit
ขั้นตอนแรกจะส่งSIGTERM
ไปยังกระบวนการต่างๆเมื่อคุณปิดระบบคอมพิวเตอร์ของคุณจากนั้นหลังจากการหน่วงเวลาจะส่งSIGKILL
หากพวกเขายังไม่ออก กระบวนการไม่สามารถจัดการ / เพิกเฉยSIGKILL
ได้
เพื่อให้รายละเอียดเพิ่มเติมเล็กน้อยคำตอบที่แท้จริงคือคุณไม่มีทางรู้แน่ชัดว่าโปรแกรมนั้นจัดการกับมัน SIGTERM
เป็นสัญญาณปกติที่สุดที่ใช้สำหรับขอให้โปรแกรมออกอย่างสุภาพ แต่การจัดการสัญญาณทั้งหมดขึ้นอยู่กับโปรแกรมที่ทำบางอย่างกับสัญญาณ
ที่จะนำมันเป็นวิธีที่แตกต่างกันขึ้นอยู่กับคำตอบอื่น ๆ ถ้าคุณมีโปรแกรมที่เขียนโดย @Jos หรือ @AlexGreg แล้วพวกเขาก็คงจะต้องจัดการSIGQUIT
แต่อาจจะไม่ได้SIGTERM
และด้วยเหตุนี้การส่งSIGTERM
จะน้อย "อ่อน" SIGQUIT
กว่า
ฉันเขียนโค้ดบางส่วนเพื่อให้คุณสามารถเล่นกับมันด้วยตัวเอง บันทึกด้านล่างเป็นsignal-test.c
แล้วรวบรวมด้วย
gcc -o signal-test signal-test.c
จากนั้นคุณสามารถเรียกใช้มันและดูสิ่งที่เกิดขึ้นเมื่อคุณส่งสัญญาณที่แตกต่างกันด้วย./signal-test
killall -s <signal>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int flag = 0;
void handle_signal(int s)
{
flag = s;
}
int main(int argc, char *argv[])
{
signal(SIGTERM, handle_signal);
signal(SIGQUIT, handle_signal);
while(flag == 0){
sleep(1);
}
printf("flag is %d\n", flag);
return flag;
}
ตามที่เป็นอยู่รหัสจะจัดการทั้ง SIGTERM และ SIGQUIT อย่างงดงาม คุณสามารถลองแสดงความคิดเห็นในบรรทัดsignal(SIG...
(โดยใช้//
ที่จุดเริ่มต้นของบรรทัด) เพื่อลบตัวจัดการสัญญาณจากนั้นเรียกใช้และส่งสัญญาณอีกครั้ง คุณควรจะเห็นผลลัพธ์ต่าง ๆ เหล่านี้:
$ ./signal-test
Terminated
$ ./signal-test
Quit (core dumped)
$ ./signal-test
flag is 15
$ ./signal-test
flag is 3
ขึ้นอยู่กับว่าคุณจัดการสัญญาณหรือไม่
คุณสามารถลองละเว้นสัญญาณ:
signal(SIGTERM, SIG_IGN);
หากคุณทำเช่นนั้นการส่งSIGTERM
จะไม่ทำอะไรเลยคุณจะต้องใช้SIGKILL
เพื่อสิ้นสุดกระบวนการ
man 7 signal
รายละเอียดเพิ่มเติมใน โปรดทราบว่าการใช้signal()
วิธีนี้ถือว่าไม่ใช่แบบพกพา - มันง่ายกว่าตัวเลือกอื่น ๆ !
เชิงอรรถย่อยอีกหนึ่งเรื่อง - บน Solaris killall
พยายามฆ่ากระบวนการทั้งหมด ทั้งหมด. หากคุณเรียกใช้มันในฐานะ root คุณอาจประหลาดใจ :)