Domanda

Posso scrivere script della shell che intercettano SIGINT bene, ma non riesco a intercettare SIGQUIT.

#!/bin/bash

function die {
    echo "Dying on signal $1"
    exit 0
}

trap 'die "SIGINT"' SIGINT
trap 'die "SIGQUIT"' SIGQUIT

while true; do
    echo "sleeping..."
    sleep 5
done

L'esecuzione di questo script e la pressione di CTRL-C ha l'effetto desiderato, ma premendo CTRL-\ (che, a quanto ho capito, dovrebbe attivare SIGQUIT) non fa altro che stampare ^\ nel terminale. Perché?

Ho due teorie correnti. Il primo è che la semantica di SIGINT e SIGQUIT è diversa in modo tale che SIGQUIT viene inviato solo al processo figlio sleep, mentre SIGINT viene inviato sia al processo figlio che al processo bash genitore. Se questo è il caso, dove è documentato?

La mia seconda teoria è che bash non solo ignora (cioè, ha un gestore no-op per) SIGQUIT per impostazione predefinita (come suggerisce la pagina man), ma non gli consente affatto di essere intrappolato. Questa teoria si sovrappone alla prima teoria, poiché potrebbe essere il caso che SIGQUIT vada sia al genitore che al figlio, ma il genitore (bash) non può semplicemente intercettarlo. Se questo è il caso, esiste qualche modo per intercettare SIGQUIT in uno script bash? ... forse qualche shopt che posso impostare?

Modifica: questo è su Ubuntu 10.10 in gnome-terminal 2.32.0 con bash 4.1.5, e sì, ^\ è configurato per emettere SIGQUIT (come riportato da stty -a e confermato dall'emissione di ^\ SIGQUIT ad altri programmi come ping).

AGGIORNAMENTO: Ho appena scoperto che il problema deve essere dovuto in qualche modo a gnome-terminal. Se eseguo questo script da una console virtuale (ad esempio, ctrl-alt-f1 per uscire da X), intercetta perfettamente SIGQUIT quando premo ^\. Stessa bash e tutto, quindi l'unica differenza deve essere l'emulatore di terminale. Quindi ora la mia domanda diventa: come posso configurare gnome-terminal in modo che si comporti come la console virtuale sotto questo aspetto? Ho diff gli output di stty -a nella console virtuale e in gnome-terminal e, sebbene ci siano differenze, nulla sembra immediatamente rilevante (ad esempio, entrambi hanno quit = ^\;).

AGGIORNAMENTO 2: Un altro esperimento. Esegui semplicemente $ sleep 60 in gnome-terminal; premere ^\ e il segnale non viene rilevato. Ora esegui $ sleep 60 nella console virtuale; premere ^\ e il segnale viene catturato: il processo stampa Quit ed esce. Ma ora esegui $ ping google.com in gnome-terminal e premi ^\: il segnale viene catturato e gestito come previsto. Quindi c'è qualcosa di strano in gnome-terminal tale che SIGQUIT può essere catturato da alcuni programmi, ma non da altri, anche se gli altri lo fanno quando vengono invocati dalla console virtuale. Forse dovrei semplicemente aggiornare il mio gnome-terminal.

È stato utile?

Soluzione

Posso solo presumere che si trattasse di una sorta di bug in gnome-terminal 2.32.0;Da allora ho aggiornato a Ubuntu 11.04, con gnome-terminal 2.32.1 (e bash 4.2.8) e SIGQUIT è ora intrappolato come previsto.

Altri suggerimenti

Osservo lo stesso comportamento su Fedora 19 con XFCE: secondo ps s, bash in xfce4-terminal ha SIGQUIT ignorato, l'esecuzione di yes >/dev/null & e poi ps s mostra che anche un sottoprocesso ha SIGQUIT ignorato.Quando (dallo stesso terminale) eseguo ssh localhost, anche la shell nella sessione ssh ha SIGQUIT ignorato, ma yes >/dev/null & no.

Dato il commento sopra che menziona gnome-terminal, immagino che il bug sia nella parte comune dei due terminali: la libreria vte.Il mio è vte-0.28.2-9.fc19.x86_64.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top