Procesy mogą wybrać:
- zignoruj sygnał SIGINT zwykle wysyłany po naciśnięciu Ctrl-C(podobnie jak
trap '' INT
w powłoce) lub skorzystaj z własnego programu obsługi, który decyduje o nie kończeniu (lub nie kończy się w odpowiednim czasie).
- powiedz urządzeniu końcowemu, że znak, który powoduje wysłanie SIGINT do zadania na pierwszym planie, jest czymś innym (jak
stty int '^K'
w przypadku powłoki)
- powiedz urządzeniu końcowemu, aby nie wysyłało żadnego sygnału (jak
stty -isig
w przypadku powłoki).
Lub mogą być nieprzerwane, na przykład w trakcie wywołania systemowego, którego nie można przerwać.
W systemie Linux (ze stosunkowo nowym jądrem) możesz sprawdzić, czy proces ignoruje i / lub obsługuje SIGINT, patrząc na wynik działania
$ kill -l INT
2
$ grep Sig "/proc/$pid/status"
SigQ: 0/63858
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000002
SigCgt: 0000000000000000
SIGINT to 2. Drugi bit SigIgn powyżej to 1, co oznacza, że SIGINT jest ignorowany.
Możesz to zautomatyzować za pomocą:
$ SIG=$(kill -l INT) perl -lane 'print $1 if $F[0] =~ /^Sig(...):/ &&
$F[1] & (1<<($ENV{SIG}-1))' < "/proc/$pid/status"
Ign
Aby sprawdzić, jaki jest obecny intr
znak lub czy isig
jest włączony dla danego terminala:
$ stty -a < /dev/pts/0
[...] intr = ^C [...] isig
(powyżej intr
znaku jest ^C
(znak zwykle wysyłany przez terminal (emulator) po naciśnięciu, CTRL-Ca sygnały wejściowe nie są wyłączone.
$ stty -a < /dev/pts/1
[...] intr = ^K [...] -isig
( intr
postać jest ^K
i isig
jest wyłączona dla /dev/pts/1
).
Dla kompletności istnieją dwa inne sposoby, w jakie proces może zrobić coś, aby przestać otrzymywać SIGINT, chociaż zwykle nie jest to coś, co można by zobaczyć.
Na Ctrl+Csygnał SIGINT jest wysyłany do wszystkich procesów, w tym grupy procesów planie terminalu . Zwykle jest to powłoka, która umieszcza procesy w grupach procesów (mapowanych do zadań powłoki ) i informuje urządzenie końcowe, które jest na pierwszym planie .
Teraz proces może:
Opuść grupę procesów. Jeśli przejdzie do innej grupy procesów (dowolnej grupy procesów oprócz tej, która jest na pierwszym planie ), nie będzie już otrzymywał SIGINT po Ctrl-C(ani innych sygnałów związanych z klawiaturą, takich jak SIGTSTP, SIGQUIT). Może jednak zostać zawieszony, jeśli spróbuje odczytać (ewentualnie również w zależności od ustawień urządzenia końcowego) z urządzenia końcowego (tak jak robią to procesy w tle).
Jako przykład:
perl -MPOSIX -e 'setpgid(0,getppid) or die "$!"; sleep 10'
nie można przerwać Ctrl-C. Powyżej perl
spróbuje dołączyć do grupy procesów, której identyfikator jest taki sam jak nadrzędny identyfikator procesu. Zasadniczo nie ma gwarancji, że istnieje taka grupa procesów o tym identyfikatorze. Ale tutaj, w przypadku tego perl
polecenia uruchamianego samodzielnie po zachęcie interaktywnej powłoki, ppid będzie procesem powłoki, a powłoka zwykle będzie uruchomiona we własnej grupie procesów.
Jeśli polecenie nie jest już liderem grupy procesów (liderem tej grupy procesów pierwszego planu), wówczas uruchomienie nowej grupy procesów miałoby ten sam efekt.
Na przykład w zależności od powłoki
$ ps -j >&2 | perl -MPOSIX -e 'setpgid(0,0) or die "$!"; sleep 10'
PID PGID SID TTY TIME CMD
21435 21435 21435 pts/12 00:00:00 zsh
21441 21441 21435 pts/12 00:00:00 ps
21442 21441 21435 pts/12 00:00:00 perl
miałby ten sam efekt. ps
i perl
są uruchamiane w grupie procesowej na pierwszym planie, ale na większości powłok, ps
będzie liderem tej grupy (jak widać na ps
wyjściu powyżej gdzie pgid obu ps
i perl
jest PID ps
), więc perl
można uruchomić własną grupę procesów.
Lub może zmienić grupę procesów pierwszego planu. Zasadniczo powiedz urządzeniu tty, aby wysłało SIGINT do innej grupy procesówCtrl+C
perl -MPOSIX -e 'tcsetpgrp (0, getppid) lub die $ !; spać 5 '
Tam, perl
pozostaje w tej samej grupie procesu lecz mówi się, że urządzenie końcowe grupy procesów planie jest tym, którego identyfikator jest taki sam jak ID procesu nadrzędnego (patrz uwaga powyżej około tego).
kill -9 %
ich zabicie. Sygnału 9 nie można zignorować, podobnie jak sygnał zawieszenia. Sekwencję klawiszy CTRL + Z można teoretycznie zignorować - ale nie ma tego w praktyce.