Ich möchte das Ergebnis des zuletzt ausgeführten Befehls in einem nachfolgenden Befehl verwenden können. Beispielsweise,
$ find . -name foo.txt
./home/user/some/directory/foo.txt
Angenommen, ich möchte die Datei in einem Editor öffnen oder löschen oder etwas anderes damit tun können, z
mv <some-variable-that-contains-the-result> /some/new/location
Wie kann ich es tun? Vielleicht mit einer Bash-Variablen?
Aktualisieren:
Zur Verdeutlichung möchte ich die Dinge nicht manuell zuweisen. Was ich suche, sind so etwas wie eingebaute Bash-Variablen, z
ls /tmp
cd $_
$_
enthält das letzte Argument des vorherigen Befehls. Ich möchte etwas Ähnliches, aber mit der Ausgabe des letzten Befehls.
Letzte Aktualisierung:
Seths Antwort hat ganz gut funktioniert. Einige Dinge zu beachten:
- Vergessen Sie nicht,
touch /tmp/x
wenn Sie die Lösung zum ersten Mal ausprobieren - Das Ergebnis wird nur gespeichert, wenn der Exit-Code des letzten Befehls erfolgreich war
linux
bash
command-line
Armandino
quelle
quelle
Antworten:
Dies ist eine wirklich hackige Lösung, aber sie scheint manchmal meistens zu funktionieren. Während des Testens stellte ich fest, dass es manchmal nicht sehr gut funktionierte, wenn ein ^CBefehlszeile angezeigt wurde, obwohl ich es ein wenig optimiert habe, um mich ein bisschen besser zu verhalten.
Dieser Hack ist nur ein interaktiver Hack, und ich bin ziemlich sicher, dass ich ihn niemandem empfehlen würde. Hintergrundbefehle verursachen wahrscheinlich noch weniger definiertes Verhalten als normal. Die anderen Antworten sind eine bessere Möglichkeit, programmgesteuert zu Ergebnissen zu gelangen.
Davon abgesehen ist hier die "Lösung":
Stellen Sie diese Bash-Umgebungsvariable ein und geben Sie die gewünschten Befehle aus.
$LAST
hat normalerweise die Ausgabe, die Sie suchen:quelle
PROMPT_COMMAND='last="$(cat /tmp/last)";lasterr="$(cat /tmp/lasterr)"; exec >/dev/tty; exec > >(tee /tmp/last); exec 2>/dev/tty; exec 2> >(tee /tmp/lasterr)'
das bietet sowohl$last
und$lasterr
.No such file or directory
2> >(tee /tmp/lasterr 1>&2)
da die Standardausgabe vontee
auf Standardfehler zurückgeleitet werden muss.Ich kenne keine Variable, die dies automatisch tut . Um etwas anderes zu tun, als nur das Ergebnis zu kopieren, können Sie alles, was Sie gerade getan haben, erneut ausführen, z
Wo
!!
bedeutet die Erweiterung des Verlaufs "der vorherige Befehl"?Wenn Sie erwarten, dass es einen einzelnen Dateinamen mit Leerzeichen oder anderen Zeichen gibt, die eine ordnungsgemäße Analyse der Argumente verhindern könnten, zitieren Sie das Ergebnis (
vim "$(!!)"
). Wenn Sie es nicht in Anführungszeichen setzen, können mehrere Dateien gleichzeitig geöffnet werden, sofern sie keine Leerzeichen oder andere Shell-Parsing-Token enthalten.quelle
vim `!!`
date "+%N"
und dannecho $(!!)
Bash ist eine hässliche Sprache. Ja, Sie können die Ausgabe einer Variablen zuweisen
Hoffen Sie jedoch besser, dassfind
nur ein Ergebnis zurückgegeben wird und dass dieses Ergebnis keine "ungeraden" Zeichen enthält, wie z. B. Zeilenumbrüche oder Zeilenvorschübe, da diese stillschweigend geändert werden, wenn sie einer Bash-Variablen zugewiesen werden.Aber seien Sie besser vorsichtig, wenn Sie Ihre Variable korrekt zitieren, wenn Sie sie verwenden!
Es ist besser, direkt auf die Datei zu reagieren, z. B. mit
find
's-execdir
(siehe Handbuch).oder
quelle
echo "${MY_VAR}"
zu sehen, dass dies der Fall ist.Es gibt mehr als eine Möglichkeit, dies zu tun. Eine Möglichkeit ist die Verwendung, mit
v=$(command)
der die Befehlsausgabe zugewiesen wirdv
. Beispielsweise:Und Sie können auch Backquotes verwenden.
Aus dem Bash Beginners Guide ,
BEARBEITEN: Nach der Bearbeitung in der Frage scheint dies nicht das zu sein, wonach das OP sucht. Soweit ich weiß, gibt es keine spezielle Variable wie
$_
für die Ausgabe des letzten Befehls.quelle
Es ist sehr leicht. Verwenden Sie Anführungszeichen:
Und dann können Sie das jederzeit in der Zukunft nutzen
quelle
Disclamers:
Wenn Sie eine interaktive Shell in tmux ausführen, können Sie problemlos auf die aktuell auf einem Terminal angezeigten Daten zugreifen. Schauen wir uns einige interessante Befehle an:
Ja, das gibt uns jetzt viele Möglichkeiten :) Ich habe einen einfachen Alias eingerichtet:
alias L="tmux capture-pane; tmux showb -b 0 | tail -n 3 | head -n 1"
und jetzt benutze ich jedes Mal, wenn ich auf die letzte Zeile zugreifen muss, einfach$(L)
, um sie zu erhalten.Dies ist unabhängig von dem vom Programm verwendeten Ausgabestream (stdin oder stderr), der Druckmethode (ncurses usw.) und dem Exit-Code des Programms - die Daten müssen nur angezeigt werden.
quelle
Ich denke, Sie können möglicherweise eine Lösung finden, bei der Sie Ihre Shell auf ein Skript setzen, das Folgendes enthält:
Wenn Sie dann
$PROMPT_COMMAND
ein Trennzeichen ausgeben möchten, können Sie eine Hilfsfunktion (möglicherweise aufgerufen_
) schreiben , mit der Sie den letzten Teil dieses Protokolls erhalten, sodass Sie es wie folgt verwenden können:quelle
Sie können den folgenden Alias in Ihrem Bash-Profil einrichten:
Wenn Sie dann nach einem beliebigen Befehl 's' eingeben, können Sie das Ergebnis in einer Shell-Variablen 'it' speichern.
Beispielverwendung wäre also:
quelle
grab
Funktion , dass Kopien n - te Zeile von den letzten Befehl in der Zwischenablage gist.github.com/davidhq/f37ac87bc77f27c5027eIch habe diese
bash
Funktion gerade aus den Vorschlägen hier heraus destilliert :Dann machst du einfach:
Update : Ein anonymer Benutzer, dessen Ersetzung vorgeschlagen
echo
wurdeprintf '%s\n'
, hat den Vorteil, dass er keine Optionen wie-e
im erfassten Text verarbeitet. Wenn Sie also solche Besonderheiten erwarten oder erleben, ziehen Sie diesen Vorschlag in Betracht. Eine andere Option istcat <<<$grab
stattdessen zu verwenden .quelle
cat <<<$grab
Option erklären ?man bash
: "Here Strings: Eine Variante der Here-Dokumente. Das Format lautet:<<<word
Das Wort wird erweitert und dem Befehl an seiner Standardeingabe übergeben." Der Wert von$grab
wird alsocat
auf stdin eingespeist undcat
nur an stdout zurückgemeldet.Mit "Ich möchte das Ergebnis des zuletzt ausgeführten Befehls in einem nachfolgenden Befehl verwenden können" gehe ich davon aus, dass Sie das Ergebnis eines Befehls meinen, nicht nur finden.
Wenn das der Fall ist - xargs ist das, wonach Sie suchen.
find . -name foo.txt -print0 | xargs -0 -I{} mv {} /some/new/location/{}
ODER wenn Sie daran interessiert sind, zuerst die Ausgabe zu sehen:
find . -name foo.txt -print0
!! | xargs -0 -I{} mv {} /some/new/location/{}
Dieser Befehl behandelt mehrere Dateien und funktioniert wie ein Zauber, selbst wenn der Pfad und / oder der Dateiname Leerzeichen enthalten.
Beachten Sie den Teil mv {} / some / new / location / {} des Befehls. Dieser Befehl wird für jede Zeile erstellt und ausgeführt, die mit einem früheren Befehl gedruckt wurde. Hier wird die durch einen früheren Befehl gedruckte Zeile anstelle von {} ersetzt .
Auszug aus der Manpage von xargs:
Weitere Informationen finden Sie in der Manpage:
man xargs
quelle
Erfassen Sie die Ausgabe mit Backticks:
quelle
Normalerweise mache ich das, was die anderen hier vorgeschlagen haben ... ohne die Aufgabe:
Sie können schicker werden, wenn Sie möchten:
quelle
Wenn Sie nur Ihren letzten Befehl erneut ausführen und die Ausgabe erhalten möchten, funktioniert eine einfache Bash-Variable:
Dann können Sie Ihren Befehl für die Ausgabe ausführen mit:
Dies erzeugt einen neuen Prozess und führt Ihren Befehl erneut aus. Anschließend erhalten Sie die Ausgabe. Es klingt so, als ob Sie wirklich eine Bash-Verlaufsdatei für die Befehlsausgabe wünschen würden. Dies bedeutet, dass Sie die Ausgabe erfassen müssen, die Bash an Ihr Terminal sendet. Sie könnten etwas schreiben, um die notwendigen / dev oder / proc zu sehen, aber das ist chaotisch. Sie können auch einfach eine "spezielle Pipe" zwischen Ihrem Term und Bash mit einem Tee-Befehl in der Mitte erstellen, der zu Ihrer Ausgabedatei umleitet.
Aber beide sind Hacky-Lösungen. Ich denke, das Beste wäre der Terminator , ein moderneres Terminal mit Ausgabeprotokollierung. Überprüfen Sie einfach Ihre Protokolldatei auf die Ergebnisse des letzten Befehls. Eine Bash-Variable ähnlich der oben genannten würde dies noch einfacher machen.
quelle
Hier ist eine Möglichkeit, dies zu tun, nachdem Sie Ihren Befehl ausgeführt und entschieden haben, dass Sie das Ergebnis in einer Variablen speichern möchten:
Oder wenn Sie im Voraus wissen, dass Sie das Ergebnis in einer Variablen haben möchten, können Sie Backticks verwenden:
quelle
Alternativ zu den vorhandenen Antworten: Verwenden
while
Sie diese Option, wenn Ihre Dateinamen Leerzeichen wie das folgende enthalten können:Wie ich schrieb, ist der Unterschied nur relevant, wenn Sie Leerzeichen in den Dateinamen erwarten müssen.
NB: Das einzige integrierte Material betrifft nicht die Ausgabe, sondern den Status des letzten Befehls.
quelle
Sie können verwenden !!: 1. Beispiel:
quelle
Ich hatte ein ähnliches Bedürfnis, bei dem ich die Ausgabe des letzten Befehls in den nächsten verwenden wollte. Ähnlich wie ein | (Rohr). z.B
zu so etwas wie -
Lösung: Erstellt diese benutzerdefinierte Pipe. Ganz einfach mit xargs -
Grundsätzlich nichts, indem man eine kurze Hand für Xargs erstellt, es funktioniert wie Charme und ist wirklich praktisch. Ich füge nur den Alias in die Datei .bash_profile ein.
quelle
Dies kann mithilfe der Magie der Dateideskriptoren und der
lastpipe
Shell-Option erfolgen.Dies muss mit einem Skript erfolgen - die Option "lastpipe" funktioniert im interaktiven Modus nicht.
Hier ist das Skript, mit dem ich getestet habe:
Was ich hier mache ist:
Einstellen der Shell-Option
shopt -s lastpipe
. Ohne dies funktioniert es nicht, da Sie den Dateideskriptor verlieren.Stellen Sie sicher, dass mein stderr auch mit erfasst wird
2>&1
Weiterleiten der Ausgabe an eine Funktion, damit auf den Standarddateideskriptor verwiesen werden kann.
Festlegen der Variablen durch Abrufen des Inhalts des
/proc/self/fd/0
Dateideskriptors, der stdin ist.Ich verwende dies zum Erfassen von Fehlern in einem Skript. Wenn also ein Problem mit einem Befehl auftritt, kann ich die Verarbeitung des Skripts beenden und sofort beenden.
Auf diese Weise kann ich
2>&1 | exit_tests ; [[ "${PIPESTATUS[0]}" == "0" ]] || error_msg
hinter jedem Befehl, den ich überprüfen möchte, etwas hinzufügen .Jetzt können Sie Ihre Ausgabe genießen!
quelle
Dies ist keine reine Bash-Lösung, aber Sie können Piping mit sed verwenden, um die letzte Zeile der vorherigen Befehle auszugeben.
Lassen Sie uns zuerst sehen, was ich im Ordner "a" habe.
Dann würde sich Ihr Beispiel mit ls und cd in sed & piping in so etwas verwandeln:
Die eigentliche Magie geschieht also mit sed. Sie leiten die Ausgabe eines Befehls in sed weiter und sed druckt die letzte Zeile, die Sie als Parameter mit Back Ticks verwenden können. Oder Sie können das auch mit xargs kombinieren. ("man xargs" in der Shell ist dein Freund)
quelle
Die Shell verfügt nicht über perlähnliche Spezialsymbole, die das Echo-Ergebnis des letzten Befehls speichern.
Lernen Sie, das Pfeifensymbol mit awk zu verwenden.
Im obigen Beispiel könnten Sie Folgendes tun:
quelle
ist noch ein anderer Weg, wenn auch schmutzig.
quelle
Ich finde es etwas ärgerlich, daran zu denken, die Ausgabe meiner Befehle in eine bestimmte Datei zu leiten. Meine Lösung ist eine Funktion in meiner
.bash_profile
, die die Ausgabe in einer Datei abfängt und das Ergebnis zurückgibt, wenn Sie es benötigen.Der Vorteil bei diesem ist, dass Sie nicht den gesamten Befehl erneut
find
ausführen müssen (wenn Sie oder andere lang laufende Befehle verwenden, die kritisch sein können).Einfach genug, fügen Sie dies in Ihre
.bash_profile
:Skript
Verwendung
An diesem Punkt füge ich in der Regel nur
| catch
das Ende aller meiner Befehle hinzu, da dies keine Kosten verursacht und ich keine Befehle erneut ausführen muss, deren Fertigstellung lange dauert.Wenn Sie die Dateiausgabe in einem Texteditor öffnen möchten, können Sie Folgendes tun:
quelle