Ich weiß, dass ich den letzten Befehl in bash mit !!
ausführen kann, aber wie kann ich die letzte Ausgabezeile ausführen?
Ich denke an den Anwendungsfall dieser Ausgabe:
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
Aber ich weiß nicht, wie ich das machen kann. Ich denke an so etwas !!
, vielleicht @@
oder ähnliches?
command_not_found_handle
Shell-Funktion oder ein Skript zu ändern, das sie ausführt (normalerweise nur/usr/lib/command-not-found
). Ich denke, Sie könnten es schaffen, damit Sie interaktiv mit der Option aufgefordert werden, das Paket automatisch zu installieren, oder (wahrscheinlich besser), damit der Name des Pakets irgendwo gespeichert wird und durch Ausführen eines kurzen Befehls installiert werden kann. Das unterscheidet sich genug von dem, was Sie hier gefragt haben. Sie können eine separate Frage dazu stellen.Antworten:
Der Befehl
$(!! |& tail -1)
sollte Folgendes tun:Wie Sie sehen, wird der
sudo apt-get install git
Befehl ausgeführt.EDIT: Breaking down
$(!! |& tail -1)
$()
ist dasbash
Befehlsersetzungsmusterbash
wird!!
auf den zuletzt ausgeführten Befehl erweitert|&
Teil ist schwierig. Normalerweise nimmt Pipe|
das STDOUT des linksseitigen Befehls und übergibt es als STDIN an den Befehl auf der rechten Seite von|
. In Ihrem Fall druckt der vorherige Befehl seine Ausgabe auf STDERR als Fehlermeldung. Also, tun|
würde nicht helfen, müssen wir sowohl die STDOUT und STDERR (oder nur STDERR) auf der rechten Seite seitige Befehl zu übergeben.|&
Übergibt STDOUT und STDERR als STDIN an den rechtsseitigen Befehl. Alternativ können Sie besser nur den STDERR bestehen:tail -1
Wie üblich wird die letzte Zeile von der Eingabe gedruckt. Anstatt die letzte Zeile zu drucken, können Sie präziser sein als die Zeile, die denapt-get install
Befehl enthält :quelle
TL; DR:
alias @@='$($(fc -ln -1) |& tail -1)'
Bash Geschichte Interaktionsmöglichkeiten bieten keinen Mechanismus , um die zu untersuchen Ausgabe von Befehlen. Die Shell speichert das nicht und die Verlaufserweiterung ist speziell für Befehle, die Sie selbst ausführen lassen, oder Teile dieser Befehle.
Dies lässt den Ansatz, den letzten Befehl erneut auszuführen und sowohl stdout als auch stderr (
|&
) in eine Befehlssubstitution zu leiten . heemayls Antwort erreicht dies, kann jedoch nicht in einem Alias verwendet werden, da die Shell die Verlaufserweiterung vor dem Erweitern von Aliasen und nicht danach durchführt.Ich kann die Verlaufserweiterung auch nicht in einer Shell-Funktion zum Laufen bringen, selbst wenn ich sie in der Funktion mit aktiviere
set -H
. Ich vermute, dass!!
eine Funktion niemals erweitert wird, und ich bin mir nicht sicher, wohin sie erweitert werden würde, aber im Moment bin ich mir nicht sicher , warum dies nicht der Fall ist.Wenn Sie die Dinge so einrichten möchten, dass Sie dies mit sehr wenig Eingabe tun können, sollten Sie daher die integrierte
fc
Shell anstelle der Verlaufserweiterung verwenden, um den letzten Befehl aus dem Verlauf zu extrahieren. Dies hat den zusätzlichen Vorteil, dass es auch dann funktioniert, wenn die Verlaufserweiterung deaktiviert ist.Wie in gezeigt Gordon Davisson ‚s Antwort auf eine Alias Erstellen enthält Bash Geschichte Erweiterung (auf Super User ),
$(fc -ln -1)
simuliert!!
. Anstecken diese in für!!
in heemayl Befehl$(!! |& tail -1)
ergibt:Dies funktioniert wie
$(!! |& tail -1)
, kann aber in einer Alias-Definition enthalten sein:Nachdem Sie diese Definition ausgeführt oder in
.bash_aliases
oder.bashrc
eingefügt und eine neue Shell gestartet haben, können Sie einfach@@
(oder wie auch immer Sie den Alias genannt haben) eingeben, um zu versuchen, die letzte Ausgabezeile des letzten Befehls auszuführen.quelle
./script
, nicht , dass Sie Quelle mit der.
odersource
builtin - ich bin nicht sicher. Bash wird beim Beenden der Shell oder beim Ausführenhistory
mit-a
oder an eine Datei angehängt-w
(siehehelp history
). In diesem Fall würden Befehle in mehreren interaktiven Shells verschachtelt (in der Reihenfolge, in der Sie sie ausgeführt haben). Sie können es sofort anhängen lassen. . Aber ich denke, es gibt noch mehr zu tun, umfc
in einem Skript zu arbeiten. Ich schlage vor, eine neue Frage dazu zu stellen. Wenn Sie dies tun, können Sie dies hier mit einem Link kommentieren.Wenn Sie einen Terminal - Emulator unter X verwenden, wie
gnome-terminal
,konsole
oderxterm
können Sie die X - Auswahl für so etwas wie Kopie verwenden und fügen Sie ihn:Verwenden Sie die primäre Auswahl
Wählen Sie die gesamte Zeile aus , die mit einem dreifachen Linksklick ausgeführt werden soll .
Dann fügen Sie ihn in die Befehlszeile unter Verwendung eines mittleren Knopf klicken .
Dies sollte in den meisten Terminalemulatoren funktionieren. Es nutzt die primäre Auswahl, ohne die Zwischenablage zu berühren - sie sind getrennt.
Es wird ausgewählt und dann technisch in einem Arbeitsgang kopiert und eingefügt.
quelle
Wie Eliah Kagan erwähnte , speichert die Shell die Befehlsausgabe nicht. Es gibt jedoch eine Möglichkeit, die letzte Ausgabezeile des letzten Befehls abzurufen, ohne den Befehl erneut auszuführen, wenn Sie den Bildschirm ausführen .
Fügen Sie die folgenden Zeilen ein
~/.screenrc
:Anschließend können Sie Ctrl+ drücken at, um die vorherige Zeile in die aktuelle Eingabeaufforderung einzufügen. Es ist möglich, dass dies auch automatisch die Eingabetaste drückt, aber es ist wahrscheinlich eine bessere Idee, dies vor dem Ausführen zu überprüfen und einfach die Eingabetaste manuell zu drücken.
Wie es funktioniert:
register t
registriert eine Zeichenfolge in einem Puffer mit dem Nament
. Die folgende Zeichenfolge ist eine Tastenfolge.bind t
bindet an den Schlüssel t(dh mit Ctrl+ ausführen at),process t
bedeutet, den Inhalt des genannten Puffers auszuwertent
.^a[
(= Ctrla[): Kopiermodus aufrufenk
Gehen Sie eine Zeile nach oben,0
gehen Sie zum Anfang der Zeile,y$
kopieren Sie bis zum Ende der Zeile, (Leerzeichen) führen Sie den Befehl aus^a]
(= Ctrla]): Kopierten Inhalt einfügen^a^L
(= CtrlaCtrlL) Aktualisieren Sie den Bildschirm (andernfalls wird der eingefügte Inhalt nicht angezeigt, da Sie ihn nicht selbst eingegeben habenquelle