Bash script non vede SIGHUP?


11

Ho il seguente script:

#!/bin/bash
echo "We are $$"
trap "echo HUP" SIGHUP
cat    # wait indefinitely

Quando invio SIGHUP(usando kill -HUP pid), non succede nulla.

Se cambio leggermente lo script:

#!/bin/bash
echo "We are $$"
trap "kill -- -$BASHPID" EXIT    # add this
trap "echo HUP" SIGHUP
cat    # wait indefinitely

... quindi lo script fa la echo HUPcosa giusta quando esce (quando premo Ctrl + C):

roger@roger-pc:~ $ ./hupper.sh 
We are 6233
^CHUP

Cosa sta succedendo? Come devo inviare un segnale (non deve essere necessariamente SIGHUP) a questo script?


4
Il segnale verrà consegnato e il gestore del segnale verrà eseguito al termine del catprocesso. Prova lo script originale e premi Ctrl+Dper catuscire dal processo. Mentre il catprocesso è in primo piano, il HUPsegnale non viene attivato. Riprovare con catsostituito da read(una shell integrata).
Kusalananda

Perfetto. Qualcuno ha voglia di trasformarlo in una risposta?
Roger Lipscombe,

So che funziona in questo modo, ma permetterò a qualcuno che ha più informazioni di me sui perché e sui perché la risposta.
Kusalananda

Alla while true; do read; donefine l' ho usato , altrimenti l'immissione del testo provoca anche la chiusura del messaggio e voglio che si chiuda su Ctrl + C.
Roger Lipscombe,

Risposte:


21

Il manuale di Bash afferma:

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.

Ciò significa che nonostante il segnale sia ricevuto da bashquando lo invii, la tua trap su SIGHUP verrà chiamata solo quando cattermina.

Se questo comportamento non è desiderabile, utilizzare i bashbuiltin (ad es. read+ printfIn un ciclo anziché cat) oppure utilizzare i processi in background (vedere la risposta di Stéphane ).


9

@xhienne ha già spiegato il perché , ma se si desidera che il segnale venga immediatamente attivato (e non si esce dallo script), è possibile modificare il codice in:

#! /bin/bash -
interrupted=true
trap 'interrupted=true; echo HUP' HUP

{ cat <&3 3<&- & pid=$!; } 3<&0

while
  wait "$pid"
  ret=$?
  "$interrupted"
do
  interrupted=false
done
exit "$ret"

La piccola danza con i descrittori di file è di aggirare il fatto che bashreindirizza lo stdin a /dev/nullcomandi lanciati in background.


Funziona perché il blocco di codice viene eseguito in una subshell?
Pysis,
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.