Gibt es eine Verknüpfung zum Ausführen einer Reihe von Befehlen im Bash-Verlauf?

20

Angenommen, ich habe das folgende triviale Beispiel in meinem history:

...
76 cd ~
77 ./generator.sh out.file
78 cp out.file ~/out/
79 ./out/cleaner.sh .
80 ls -alnh /out
...

Wenn ich wollte , um Befehle auszuführen 77, 78und 79in einem Befehl, Gibt es eine Abkürzung für das? Ich habe versucht !77 !78 !79, die einfach alle in einer einzigen Zeile auszuführen.

MrDuk
quelle
9
Ist !77 ; !78 ; !79okay
Thrig
1
Ich denke, alles andere als zeilenweise zu !77-79
tippen ist in Ordnung
1
@ MrDuk, Junge, das hat eine Weile gedauert, bis ich mich erinnere. Siehe meine aktualisierte Antwort für die sehr prägnante Lösung! :)
Wildcard
Es ist magisch! :)
MrDuk

Antworten:

28

BEARBEITEN: Sie können dies POSIX-konform mit dem Befehlstool fix ausführenfc :

fc 77 79

Dies öffnet Ihren Editor (wahrscheinlich vi) mit den Befehlen 77 bis 79 im Puffer. Wenn Sie speichern und beenden ( :x), werden die Befehle ausgeführt.


Wenn Sie sie nicht bearbeiten möchten und SEHR SICHER sind, welche Befehle Sie aufrufen, können Sie Folgendes verwenden:

fc -e true 77 79

Dies wird trueals "Editor" verwendet, um die Befehle mit zu bearbeiten. Es wird nur beendet, ohne dass Änderungen vorgenommen werden, und die Befehle werden so ausgeführt, wie sie sind.


URSPRÜNGLICHE ANTWORT:

Sie können verwenden:

history -p \!{77..79} | bash

Dies setzt voraus, dass Sie keine Aliase oder Funktionen oder Variablen verwenden, die nur in der aktuellen Ausführungsumgebung vorhanden sind, da diese natürlich in der neu gestarteten Shell nicht verfügbar sind.


Eine bessere Lösung (danke an Michael Hoffman, der mich in den Kommentaren erinnert hat) ist:

eval "$(history -p \!{77..79})"

Einer der ganz wenigen Fälle, in denen evales tatsächlich angebracht ist!


Siehe auch:

Platzhalter
quelle
2
Dies funktioniert nicht ordnungsgemäß, wenn einer der Befehle die aktuelle Ausführungsumgebung ändert , z. B. durch Ändern einer Variablen oder Ausführen von a. Dies cdist jedoch ein Randfall.
G-Man sagt, dass Monica
3
eval "$(history -p \!{77..79})"sollte arbeiten.
Michael Hoffman
1
@MichaelHoffman, ich hatte darüber nachgedacht und gedacht, ich hätte es versucht, aber mir ist nur klar geworden, dass ich das Zitieren ausgelassen habe! D'oh! Kein Wunder, dass es nicht geklappt hat.
Wildcard
14

Einfache Antwort: statt !77 !78 !79,

  • Geben Sie ein !77; !78; !79, um das zu tun, was Sie zu tun versuchen - führen Sie den Befehl 77 und dann den Befehl 78 und dann den Befehl 79 bedingungslos aus, oder
  • Geben Sie ein !77 && !78 && !79 , um den Befehl 77 auszuführen und zu prüfen, ob er erfolgreich war. Wenn der Befehl 77 erfolgreich war, führen Sie den Befehl 78 aus. Wenn der Befehl 78 erfolgreich war, führen Sie den Befehl 79 aus.

Etwas cleverere Antwort (wenn Sie sich in einem Terminal-Fenster befinden):

  • Finden Sie heraus, welche Befehlsnummer der nächste eingegebene Befehl sein wird.
    • Es ist möglich, dies in Ihre Eingabeaufforderung aufzunehmen. Ich glaube, es ist durch die Aufnahme \!in Ihre PS1.
    • Oder sehen Sie sich Ihre Verlaufsliste an. Wenn der letzte Eintrag lautet 82 history, lautet Ihr nächster Befehl 83.
  • Subtrahiere 83−77 = 6.
  • Typ !-6. Dadurch wird der Befehl 77 erneut ausgeführt.
  • Wählen Sie die aus !-6, kopieren Sie sie und fügen Sie sie ein. Da Ihre erneute Ausführung von Befehl 77 ( ./generator.sh) Befehl 83 war, befinden Sie sich jetzt in Befehl 84 und !-6führen Befehl 78 erneut aus.
  • Wiederholen Sie das Einfügen !-6nach Wunsch.
G-Man sagt, "Monica wiedereinsetzen"
quelle