Wie kann ich den Rest einer Befehlsliste in Bash abbrechen?

10

In Bash werde ich gelegentlich eine Liste von Befehlen eingeben und drücken Enterund erst später feststellen, dass am Ende der Liste ein Fehler mit einem Befehl vorliegt. Ich weiß, dass wenn ich Ctrl+ drücke C, der aktuell ausgeführte Befehl beendet und der Rest der Liste abgebrochen wird. Gibt es eine Möglichkeit, den Rest der Liste abzubrechen, ohne den aktuell ausgeführten Befehl zu beenden?

Nehmen wir zum Beispiel an, ich habe so etwas eingegeben

foo; bar

oder

foo && bar

Wo fooist ein lang laufender Befehl, dass es sehr wichtig ist, nicht zu unterbrechen, und baretwas irreversibles und unerwünschtes tut (sagen wir shutdown -h nowoder rm -rf /). Gibt fooes eine allgemeine Möglichkeit, der Shell zu sagen, dass sie foofertig sein soll, aber nicht bardanach laufen soll, während sie noch läuft ? (Ja, ich könnte die Berechtigungen barso ändern , dass sie nicht ausführbar sind, aber das ist nicht besonders praktisch, wenn ich so baretwas rmin der Zwischenzeit verwenden möchte, und es funktioniert auch nicht, wenn ich es nicht besitze baroder wenn bares integriert ist.)

Psychonaut
quelle
Sie können den letzten barBefehl in some_command: ändern , ^bar^some_commandbevor er ausgeführt wird.
GAD3R
3
@ GAD3R: Dies ändert jedoch nicht die aktuelle Zeile, sondern startet eine neue.
Arkadiusz Drabczyk

Antworten:

3

Ich habe beobachtet, dass CtrlZdas Verschieben des Programms in einen Hintergrundprozess den Trick macht.

foo && bar

Vielen Dank an @Arkadiusz Drabczyk für den Hinweis in Kommentaren, foo; bardie nicht die erforderliche Kontrolle geben.

Dann:

^Z

[1]+  Stopped                 foo

Der Befehl stoppt nur die erste Aufgabe und

fg %1

Dies bringt nur die Aufgabe fooin den Vordergrund und schließt die Aufgabe ab und beendet sie.

PS: Dies kann mit zwei Skripten überprüft werden, die in eine Datei schreiben. Der erste, der ein paar Sekunden schläft, um Zeit zum Zurücksetzen zu haben.

Ich habe keine Ahnung, warum der CtrlZBefehl nur ausgeführt wird und der Rest übrig bleibt. Würde gerne kennenlernen.

Revanth Chetluru
quelle
1
Ich kann es nicht reproduzieren. Welche bashVersion benutzt du? Ich benutze GNU bash, version 4.3.46(1)-release (x86_64-slackware-linux-gnu). Ich schrieb 2 Bash - Skripte , dass Schreiben auf verschiedene Dateien: write1.sh: pastebin.com/rbKmdWgB und write2.sh: pastebin.com/bNx3VRws . Ich führe sie so : ./write1.sh ; ./write2.sh. Das erste Skript hallt wrote 1ein paar Mal wider , ich drücke C-z, es heißt [1]+ Stopped ./write1.shund ich kann sofort die Ausgabe des zweiten Skripts sehen: wrote 2wiederholt wiederholt werden.
Arkadiusz Drabczyk
2
Ich denke, der Grund, warum diese Methode mit command1 && command2Pipelines funktioniert, ist, dass sie ein Signal an den Prozess Control-zsendet SIGCHLD. Es kann mit überprüft werden echo $?. Bashstellt dann fest, dass der erste Prozess nicht erfolgreich abgeschlossen wurde und die nächsten Prozesse nicht ausgeführt werden.
Arkadiusz Drabczyk
Ich benutze GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16). Ja, ich denke du hast recht. foo; barkann nicht auf die gewünschte Weise gesteuert werden. Aber wir können den erforderlichen Stopp des zweiten Prozesses mit Ctrl+Zausführen, wenn der Befehl ausgeführt wird foo && bar. Ich werde die Antwort aktualisieren. Vielen Dank für den Hinweis.
Revanth Chetluru
@ArkadiuszDrabczyk sendet Strg-Z kein SIGTSTP?
Muru
@ RevanthChetluru Hinweis, der barimmer noch ausgesetzt ist und in der jobsAusgabe angezeigt wird, sollte wahrscheinlich auch getötet werden.
Muru