Trap 'Strg + c' für Bash-Skript, aber nicht für in diesem Skript geöffnete Prozesse

11

Ich habe versucht, ein interaktives Programm in einem Bash-Skript zu haben:

my_program

Und ich möchte es mit 'Strg + c' schließen können. Aber wenn ich es mache, wird auch mein Skript geschlossen.

Ich weiss Bescheid.

trap '' 2
my_program
trap 2

Aber in diesem Fall kann ich einfach nicht my_programmit Strg + c schließen.

Haben Sie eine Idee, wie Sie Strg + C in einem Programm zulassen, aber das Skript, in dem es ausgeführt wird, nicht schließen können?

BEARBEITEN: Beispiel hinzufügen

#!/bin/bash
my_program
my_program2

Wenn ich Strg + C zum Schließen benutze my_program, my_program2wird es nie ausgeführt, weil das gesamte Skript beendet wird.

Bob Dylan
quelle

Antworten:

13

Sie sollten trap true 2oder trap : 2anstelle von verwenden trap '' 2. Das sagt "Hilfefalle" in einer Bash-Shell darüber:

Wenn ARG die Nullzeichenfolge ist, wird jede SIGNAL_SPEC von der Shell und den von ihr aufgerufenen Befehlen ignoriert .

Beispiel:

$ cat /tmp/test
#! /bin/sh
trap : INT
cat
echo first cat killed
cat
echo second cat killed
echo done
$ /tmp/test
   <press control-C>
^Cfirst cat killed
   <press control-C>
^Csecond cat killed
done
Mosvy
quelle
2
Wie wäre es, tailwenn Sie das nächste Mal s töten, anstatt Katzen zu töten?
Kubanczyk
12

Sie können eine Trap auf ihre Standardeinstellung zurücksetzen, indem Sie den Befehl trap -als Aktionsargument angeben. Wenn Sie dies in einer Subshell tun, hat dies keine Auswirkungen auf die Falle in der übergeordneten Shell. In Ihrem Skript können Sie dies für jeden Befehl tun, den Sie mit Strg-C unterbrechen müssen:

#!/bin/bash
# make the shell (and its children) ignore SIGINT
trap '' INT
.
.
.
# but this child won't ignore SIGINT
(trap - INT; my_program)
# the rest of the script is still ignoring SIGINT
.
.
.
Mark Plotnick
quelle
1
Während die akzeptierte Antwort für Shell wahrscheinlich besser und kanonischer ist, ist dies eine großartige Antwort für sich, da sie das allgemeine Prinzip (nicht Shell-spezifisch) einführt, wie diese Art der Signalmaskierung / -sicherheit sicher durchgeführt werden kann.
R .. GitHub STOP HELPING ICE
Ich denke, Sie können exec my_programin der Subshell etwas effizienter sein.
Toby Speight
@R .. das ist absolut nicht Shell-spezifisch - wenn Sie ein Signal auf SIG_IGN setzen (das macht Trap mit einer leeren Zeichenfolge), wird dieser Status mit Ausnahme von SIGCHLD über exec () vererbt. Das ist POSIX-vorgeschriebenes Verhalten. Siehe auch die Antwort auf stackoverflow.com/questions/32708086/…
mosvy
@mosvy: Ich sehe nicht, mit welchem ​​Teil meines Kommentars Sie nicht einverstanden sind. Mein ganzer Punkt war, dass "Maske / Ignorieren vor dem Verzweigen, Demaskieren / Unignore im Kind vor der Ausführung" ein allgemeines Prinzip ist, das außerhalb des Kontexts der reinen Shell-Programmierung zu wissen ist.
R .. GitHub STOP HELPING ICE
1
Dies ist eine sehr nützliche Antwort. Als erfahrener Linux-Benutzer kann ich sagen, dass ich noch nie davon gehört habe. Es hat ziemlich viele Verwendungszwecke ... Sie haben meine Gegenstimme und mein Lesezeichen erhalten.
Dev
-1


Wenn Sie Crtl+ verwenden C, unterbrechen Sie das Programm (" töten " Sie es).
Was Sie wahrscheinlich suchen, ist , Ihr Programm anzuhalten (" pausieren "). Hierfür können Sie Crtl+ verwenden Z.
Sobald Ihr Programm angehalten ist, können Sie es mit sehen jobs. Zum Beispiel:
[1]+ Stopped ./foobar
Hier habe ich nur einen Job, Job Nr. 1, aber es kann mehr als einen geben - jeder Job hat seine eigene Nummer.
Sie können Sie suspendierte Prozess steuern , um eine Reihe von Befehlen, zum Beispiel bg, fgund kill.
bg %1Job # 1 in der wird neu gestartet b ack g Runde
fg %1wird erneut gestartet Job # 1 in f oreg round beendet
kill %1Job Nr. 1.
Beachten Sie, dass Sie bgund fgohne Argumente verwenden können, wenn Sie nur einen aktiven Job haben.

pi0tr
quelle
Danke, aber nein, ich möchte Strg + c machen.
Bob Dylan