2012-10-10 8 views
8

Ho uno script bash che monta e smonta un dispositivo, che esegue alcune operazioni di lettura intermedie. Poiché il dispositivo è molto lento, lo script impiega circa 15 secondi per essere completato (il montaggio richiede almeno 5-6 secondi). Dato che lasciare questo dispositivo montato può causare altri problemi, non voglio che questo script venga interrotto.Script Bash: impossibile gestire SIGTSTP

Detto questo, posso gestire correttamente SIGINT (Ctrl + c), ma quando provo a gestire SIGTSTP (Ctrl + z), lo script si blocca. Il che significa che il segnale è intrappolato ma il gestore non funziona.

#!/bin/sh 
cleanup() 
{ 
    # Don't worry about unmounting yet. Just checking if trap works. 
    echo "Quitting..." > /dev/tty 
    exit 0 
} 
trap 'cleanup' SIGTSTP 
... 

Devo inviare manualmente il segnale KILL al processo. Qualche idea del perché questo sta accadendo e come posso risolverlo?

risposta

4

La shell non esegue il trap finché non termina il processo in esecuzione. (almeno, questo è il comportamento di bash 3.00.15). Se si invia SIGINT tramite^c, questo viene inviato a tutti i processi nel gruppo di processi in primo piano; se il programma attualmente in esecuzione lo riceve e termina, bash può eseguire la trappola. Allo stesso modo con SIGTSTP tramite^z; bash riceve il segnale ma non esegue il trap fino a quando il programma in esecuzione non termina, cosa che non avviene se prende il comportamento predefinito e viene sospeso. Prova a sostituire ... con un semplice read f e nota che la trap viene eseguita immediatamente.

+0

Questo ha molto senso. Quindi sembra che a meno che tutti i binari che esegui con lo script gestiscano anche^z come fai tu, non c'è modo di gestire correttamente^z. È giusto? – Ram

+0

È possibile eseguire il lavoro in modo asincrono sotto setsid e attendere. es .: 'setsid cmd & wait' invece di solo' cmd'. –

+0

Sembra farlo. Grazie per il tuo aiuto! Ma solo curioso, il processo non si fermerà ancora in una nuova sessione? – Ram