2010-03-31 12 views
6

Ho scritto uno script Bash piccolo per trovare tutti i gruppi di modifiche Mercurial (a partire dalla punta) che contiene la stringa passata in argomento:Bash: come interrompere questo script quando c'è un CTRL-C?

#!/bin/bash 

CNT=$(hg tip | awk '{ print $2 }' | head -c 3) 
while [ $CNT -gt 0 ] 
do 
    echo rev $CNT 
    hg log -v -r$CNT | grep $1  
    let CNT=CNT-1 
done 

Se interrompo che colpendo Ctrl-C, il più delle volte il il comando attualmente eseguito è "hg log" ed è quel comando che viene interrotto, ma poi il mio script continua.

Mi è stato poi pensando di verifica dello stato di ritorno "hg log", ma perché sto tubazioni in grep io non sono troppo sicuro di come andare a questo proposito ...

Come dovrebbe Vado in uscita da questo script quando viene interrotto? (btw non so se questo script è buono per quello che voglio fare ma fa il lavoro e comunque sono interessato al problema "interrotto")

risposta

5

riscrivere il vostro script come questo, utilizzando l'array $ PIPESTATUS per verificare la presenza di un fallimento:

#!/bin/bash 

CNT=$(hg tip | awk '{ print $2 }' | head -c 3) 
while [ $CNT -gt 0 ] 
do 
    echo rev $CNT 
    hg log -v -r$CNT | grep $1 
    if [ 0 -ne ${PIPESTATUS[0]} ] ; then 
      echo hg failed 
      exit 
    fi  
    let CNT=CNT-1 
done 
+0

Grazie mille, +1 a tutti. Funzionando bene :) – SyntaxT3rr0r

+0

Dovrei probabilmente indicare che sia $ PIPESTATUS che l'opzione pipefail che Arkku ha menzionato sono specifiche di Bash versione 3+. Non sono supportati da altre shell. –

+0

grazie, sui miei Debian Linux ho effettivamente Bash 3+ ma sui miei Mac è Bash 2.05. – SyntaxT3rr0r

1

La variabile $PIPESTATUS ti permetterà di controllare i risultati di ogni membro della pipa.

6

luogo all'inizio del vostro script: trap 'echo interrupted; exit' INT

Edit: Come notato nei commenti qui sotto, probabilmente non funziona per il programma del PO a causa del tubo. La soluzione $PIPESTATUS funziona, ma potrebbe essere più semplice per impostare lo script per uscire da se qualsiasi programma nelle uscite tubi con uno stato di errore: set -e -o pipefail

+0

Il comando trap funziona solo con i processi che non intercettano gli stessi interrupt. Se lo script stava ricevendo l'interrupt, si sarebbe già abortito. –

+0

Ah, mi dispiace, ho perso la pipa nella sceneggiatura dell'OP. Una risposta migliore potrebbe essere: set -e pipefail – Arkku

+0

La tua prima soluzione (il trap) funzionerebbe con qualsiasi processo che non intercettasse le interruzioni stesse - * find * è un buon esempio di un processo di lunga durata che passare attraverso l'interruzione, causando l'interruzione dello script. Il trap può essere usato per evitare che lo script si interrompa immediatamente per eseguire la pulizia, un po 'come un distruttore o un finalizzatore. È un comando pratico da conoscere. –