2014-03-25 5 views
7

Ich habe mehrere Skripte mit while read line Schleifen, die nicht die Bereinigungsfunktion ausführen, wenn ich Ctrl C drücken Zum Beispiel:Bash-Skript nicht fangen SIGINT während in Leseschleife

#!/bin/bash 

cleanup() { 
    stty echo 
    exit 0 
} 

trap cleanup SIGINT SIGHUP SIGTERM 

stty -echo 
while read -r line; do 
    echo "$line" 
done < /foo/bar 

cleanup 

Wenn ich drücken Strg- C, mein Terminal ist vermasselt, weil die stty -echo Einstellung immer noch in Kraft ist. Ich habe viele andere Skripte, bei denen meine Aufräumfunktion einwandfrei funktioniert. Das einzige Mal, dass ich ein Problem habe, ist, wenn ich Ctrl-C drücke, während sich das Skript in einer read Schleife befindet. Gibt es eine Möglichkeit, sicherzustellen, dass die Funktion cleanup aufgerufen wird, wenn Strg-C gedrückt wird, während das Skript in einer read-Schleife ist? Oder verpasse ich hier gerade etwas Offensichtliches?

Update: Es gibt etwas anderes in meinen Skripts. Ich habe genau das obige Skript ausgeführt, und ich kann es nicht so scheitern lassen, wie es meine anderen Skripte tun. Ich muss versuchen, die fehlerhaften Skripte zu etwas zu destillieren, das ich bekommen kann, um zu scheitern, an welchem ​​Punkt ich die Frage aktualisieren werde.

Update 2: Okay, ich habe es herausgefunden. Ich bekam einen Fehler von stty (den ich nicht sah, weil meine wirkliche Aufräumfunktion auch den Bildschirm löschte). Der Fehler war: stty: standard input: Inappropriate ioctl for device. Ich sah dies oben ein anscheinend war es, stty zu benennen, während stdin von der Datei /foo/bar umgeleitet wurde. Also änderte ich meinen trap Anruf zu trap "break" SIGINT SIGHUP SIGTERM und es funktionierte.

+0

versuchen Sie dies: https://Stackoverflow.com/a/13058864/2591612 – Brian

+0

Das war ein Tippfehler. Mein aktuelles Skript verwendet '<'. Es tut uns leid. –

+0

Bitte posten Sie Ihre Lösung als Antwort und akzeptieren Sie sie, sobald Sie können. –

Antwort

4

Es stellt sich heraus, das Problem auf die Tatsache zurückzuführen war, dass meine cleanup Funktion stty anrief und stty mag offenbar nicht genannt werden, während stdin aus einer Datei umgeleitet wird. Wenn ich also Strg-C gedrückt wird, während das Skript die read Schleife ausgeführt wurde, die cleanup Funktion wurde wie genannt, wenn ich es innerhalb der Schleife aufgerufen hatte:

while read -r line; do 
    ... 
    cleanup 
    ... 
done < "$filename" 

Dies wiederum bedeutete, dass stty ausgeführt wurde mit einer Umleitung stdin, und es starb mit dem Fehler stty: standard input: Inappropriate ioctl for device.

Ich konnte dies meine trap Linie durch Änderung beheben:

trap "break" SIGINT SIGHUP SIGTERM 

Also anstatt es effektiv um einen Anruf zu cleanup in meine Schleife einfügen, wenn ich Strg-C drücken, es stattdessen nur (effektiv) fügt eine break in die Schleife ein, bricht so aus der Schleife heraus und ruft anschließend die Funktion cleanup über die Leitung nach der Schleife auf.

Verwandte Themen