Mój program serwera odebrał SIGTERM i zatrzymał się (z kodem zakończenia 0). Dziwię się tym, bo jestem prawie pewien, że było na to dużo pamięci. W jakich warunkach linux (busybox) wysyła SIGTERM do procesu?
Komentarze
Odpowiedz
Opublikuję to jako odpowiedź, więc że istnieje jakieś rozwiązanie, jeśli okaże się, że to jest problem.
Kod zakończenia równy 0 oznacza normalne wyjście z pomyślnie zakończonego programu. program wychodzący może wybrać dowolną liczbę całkowitą od 0 do 255 jako swój kod zakończenia. Zwykle programy używają małych wartości. Wartości 126 i wyższe są używane przez powłokę do zgłaszania specjalnych warunków, więc najlepiej ich unikać.
Na poziomie C API programy raportują 16-bitowy status¹ , który koduje zarówno status wyjścia programu, jak i sygnał, który go zabił, jeśli taki istnieje.
W powłoce a polecenie „s status wyjścia (zapisane w $?
) łączy rzeczywisty status wyjścia programu z wartością sygnału: jeśli program zostanie zabity przez sygnał, $?
jest ustawione na wartość większą niż 128 (w większości powłok ta wartość to 128 plus numer sygnału; ATT ksh używa 256 + numer sygnału, a yash używa 384 + numer sygnału, co pozwala uniknąć niejednoznaczność, ale inne powłoki nie poszły w ich ślady).
W szczególności, jeśli $?
wynosi 0, program zakończył normalnie.
Zauważ, że obejmuje to przypadek procesu, który odbiera SIGTERM, ale ma dla niego obsługę sygnału i ostatecznie kończy normalnie (być może jako pośrednia konsekwencja sygnału SIGTERM, być może nie).
Aby odpowiedzieć na pytanie w twoim tytule, SIGTERM nigdy nie jest wysyłany automatycznie przez system. Jest kilka sygnałów, które są wysyłane automatycznie, jak SIGHUP, gdy terminal znika, SIGSEGV / SIGBUS / SIGILL, gdy proces robi rzeczy, których nie powinien robić, SIGPIPE, gdy zapisuje do zepsutej rury / gniazda, itp. kilka sygnałów wysyłanych po naciśnięciu klawisza w terminalu, głównie SIGINT dla Ctrl + C , SIGQUIT dla Ctrl + \ i SIGTSTP dla Ctrl + Z , ale SIGTERM nie jest jednym z nich. Jeśli proces odbiera SIGTERM, inny proces wysłał ten sygnał.
¹ z grubsza
Komentarze
- Ładne wyjaśnienie, w jaki sposób określa się stan wyjścia po otrzymaniu sygnału. Jednak ta odpowiedź nie ' nie odpowiada pytaniu OP '.
- @codeforester Odpowiedziałem na pytanie w body, a nie pytanie w tytule. Cóż, jedno z pytań w treści – biorąc pod uwagę, że było oparte na nieporozumieniu, jest trochę bałaganiarskie. I ' Dodam jeszcze kilka słów o reszcie.
- To zależy od powłoki. W ksh93 to ' s 256 + signum, w yash to ' s 384 + signum
- Zwróć uwagę, że użycie wartości powyżej 256 a la ksh niekoniecznie jest lepsze, ponieważ zapobiega przekazaniu jej do
exit
. Podejścieyash
to dobry kompromis, ale poszukaj innego rozwiązania w rc. Zobacz także Domyślny kod zakończenia po zakończeniu procesu?
Odpowiedź
SIGTERM jest sygnałem, który jest zwykle używany do administracyjnego zakończenia procesu.
To nie jest sygnał, który jądro wyśle, ale to jest sygnał, który proces zazwyczaj wysłać, aby zakończyć (wdzięcznie) inny proces.
To jest sygnał, który jest wysyłany domyślnie przez kill
, pkill
, killall
… polecenia.
To jest sygnał, który jest wysyłany do demonów w celu ich zatrzymania (np. service some-service stop
) lub wysyłany przez init
przed zamknięciem (po którym następuje SIGKILL dla tych procesów, którym nie udało się zakończyć na czas po SIGTERM).
Zauważ, że SIGTERM nie jest sygnałem wysyłanym po ^C
. Sygnał wysłany na ^C
to SIGINT.
$?
zostałby ustawiony na 143 (128 + numer sygnału).