Perché bash ignora SIGTERM?


10

A volte, quando voglio disconnettermi rapidamente, lo faccio kill -15 -1. Ho notato che bash sta ignorando SIGTERM.

Mi chiedo quale sia la logica di tale comportamento bash ?

Non è molto UNIX ignorare SIGTERM senza una buona ragione, no?

AGGIORNARE:

stesso (no) effetto per tutti:

$ kill -TERM $$
$ type kill
kill is a shell builtin
$ command kill -TERM $$
$ /bin/kill -TERM $$

UPDATE2:

Da man bash :

Quando bash è interattivo, in assenza di trappole, ignora SIGTERM

Quindi è fatto apposta. Ma perché?


Quale uccisione stai usando? /bin/killo la shell integrata? In quest'ultimo caso, suppongo che la shell non si ucciderà da sola.
terdon

@terdon: ho usato builtin, ma non penso che sia la ragione per non ucciderlo da solo.
Michał Šrajer,

1
Se vuoi disconnetterti rapidamente, usa Ctrl + d
YoMismo il

1
@YoMismo: "logout dalla sessione X"
Michał Šrajer,

2
@ MichałŠrajer: Ctrl-Alt-Backspace fa questo per me su Xorg ... potresti doverlo abilitare in xorg.conf, però.
Laszlo Valko

Risposte:


10

Innanzitutto, questo non è specifico per bash. ATT ksh, dash e zsh si comportano allo stesso modo: ignorano SIGTERM e SIGQUIT durante l'edizione da riga di comando; per quanto riguarda mksh, anche non si chiude ma li tratta come SIGINT.

Sia il manuale di ksh che il manuale di bash giustificano l'ignoranza di SIGTERM in questi termini:

in modo che kill 0non uccida una shell interattiva

kill 0uccide tutti i processi nel gruppo di processi in cui si trova la shell¹. In poche parole, il gruppo di processi è costituito da tutti i processi in esecuzione in primo piano su un terminale o da tutti i processi in background o in sospeso.

Più precisamente, questo è ciò che accade nelle shell moderne con controllo del lavoro . In tali shell, kill 0non sarebbe utile, poiché la shell sarebbe in un gruppo di processo a sé stante. Le shell più vecchie (o le shell moderne dopo set +m) non hanno creato gruppi di processi per i comandi in background. Quindi è possibile utilizzare il comando kill 0per eliminare tutti i comandi in background senza disconnettersi.² Pertanto la kill 0logica appare come una vecchia che al giorno d'oggi non è più giustificata ma mantenuta per compatibilità con le versioni precedenti.

Tuttavia ci sono altre situazioni simili in cui è utile rendere immune il guscio. Considera il caso in cui hai processi che registrano un terminale e vuoi ucciderli senza essere disconnesso. Molti sistemi hanno uno strumento come quello pkillche ti consente di uccidere i processi in esecuzione su un terminale. È possibile eseguire pkill -t $TTYo pkill -QUIT -t $TTYuccidere tutti i processi in esecuzione sul terminale corrente, tranne la shell che ignora il segnale.

Una shell normalmente scompare quando l'utente esce (con un comando simile a exito logout) o quando il suo terminale segnala la fine dell'input (l'utente può causare ciò premendo Ctrl+ D) o scompare del tutto. In quest'ultimo caso, la shell riceve il segnale SIGHUP e non lo ignora.

Per il tuo caso d'uso di disconnettersi da una sessione X, kill -15 -1lo farà, poiché uccide l'emulatore di terminale che fa sì che la shell riceva SIGHUP. È infatti sufficiente uccidere il server X, ma ciò richiede la ricerca dell'ID del processo. Se si desidera che lo stesso comando funzioni su una sessione di testo, è possibile utilizzare kill -15 -1; exit. È comunque un comando abbastanza pericoloso da avere a portata di mano.

¹ Questo non sembra essere menzionato nei manuali di shell come regola; è una caratteristica della chiamata di sistema sottostante. È menzionato esplicitamente nella specifica POSIX .
² Al giorno d'oggi, per farlo, eseguire jobs -lper visualizzare un elenco di lavori con l'ID del gruppo di processi, quindi kill -123 -456 …per terminare i gruppi di processi.


5

Questo potrebbe rispondere alla tua domanda:

Quando Bash è interattivo, in assenza di trappole, ignora SIGTERM (in modo che "kill 0" non uccida una shell interattiva) e SIGINT viene catturato e gestito (in modo che l'attesa di attesa sia interrompibile). Quando Bash riceve un SIGINT, esce da qualsiasi ciclo di esecuzione. In tutti i casi, Bash ignora SIGQUIT. Se il controllo lavoro è attivo (vedere Controllo lavoro), Bash ignora SIGTTIN, SIGTTOU e SIGTSTP.

I comandi non integrati avviati da Bash hanno gestori di segnali impostati sui valori ereditati dalla shell dal suo genitore. Quando il controllo dei lavori non è attivo, i comandi asincroni ignorano SIGINT e SIGQUIT oltre a questi gestori ereditati. I comandi eseguiti a seguito della sostituzione dei comandi ignorano i segnali di controllo lavoro generati dalla tastiera SIGTTIN, SIGTTOU e SIGTSTP.

La shell esce di default al ricevimento di un SIGHUP. Prima di uscire, una shell interattiva rinvia SIGHUP a tutti i lavori, in esecuzione o arrestati. I lavori interrotti vengono inviati a SIGCONT per garantire che ricevano il SIGHUP. Per impedire alla shell di inviare il segnale SIGHUP a un particolare lavoro, è necessario rimuoverlo dalla tabella dei lavori con la funzione incorporata disconnessa (consultare la pagina relativa ai Controlli dei lavori) o contrassegnata per non ricevere SIGHUP usando disown -h.

Se l'opzione della shell huponexit è stata impostata con shopt (vedi The Shopt Builtin), Bash invia un SIGHUP a tutti i lavori quando esce una shell di login interattiva.

Se Bash è in attesa del completamento di un comando e riceve un segnale per il quale è stata impostata una trap, la trap non verrà eseguita fino al completamento del comando. Quando Bash è in attesa di un comando asincrono tramite l'attesa incorporata, la ricezione di un segnale per il quale è stata impostata una trap farà sì che l'attesa incorporata ritorni immediatamente con uno stato di uscita maggiore di 128, immediatamente dopo il quale viene eseguita la trap.

FONTE : il manuale GNU Bash


L'ho citato nel mio aggiornamento2. L'uomo afferma che Bash lo sta facendo, ma non spiega perché tale decisione. La domanda rimane: perché?
Michał Šrajer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.