wake-up-neo.com

Ausgabe des letzten Befehls in Bash wiederverwenden

Ist die Ausgabe eines Bash-Befehls in einem beliebigen Register gespeichert? Z.B. Ähnlich wie $? die Ausgabe anstelle des Beendigungsstatus erfasst.

Ich könnte die Ausgabe einer Variablen zuweisen mit: 

output=$(command)

aber das ist mehr tippen ... 

112
memecs

Sie können Folgendes verwenden: $(!!), um die Ausgabe des letzten Befehls erneut zu berechnen (nicht erneut zu verwenden).

Der !! alleine führt den letzten Befehl aus.

$ > echo pierre
pierre
$ > echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre
123
ling

Die Antwort ist nein. Bash weist keinem Parameter oder Block in seinem Speicher keine Ausgabe zu. Außerdem können Sie nur über die zulässigen Schnittstellenvorgänge auf Bash zugreifen. Auf die privaten Daten von Bash kann nur zugegriffen werden, wenn Sie sie hacken.

67
konsolebox

Eine Möglichkeit, dies zu tun, ist die Verwendung von trap DEBUG:

f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUG

Die zuletzt ausgeführten Befehle stdout und stderr sind jetzt in /tmp/out.log verfügbar.

Der einzige Nachteil ist, dass ein Befehl zweimal ausgeführt wird: einmal, um die Ausgabe und den Fehler zu /tmp/out.log umzuleiten, und einmal normal. Wahrscheinlich gibt es auch eine Möglichkeit, dieses Verhalten zu verhindern.

8
anubhava

Inspiriert von der Antwort von anubhava, die meiner Meinung nach nicht akzeptabel ist, da sie jeden Befehl zweimal ausführt.

save_output() { 
   exec 1>&3 
   { [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
   exec > >(tee /tmp/current)
}

exec 3>&1
trap save_output DEBUG

Auf diese Weise befindet sich die Ausgabe des letzten Befehls in/tmp/last und der Befehl wird nicht zweimal aufgerufen.

3
olivecoder

Wenn Sie sich auf einem Mac befinden und die Ausgabe in der Zwischenablage speichern möchten, anstatt in eine Variable zu schreiben, können Sie pbcopy und pbpaste als Workaround verwenden.

Anstatt zum Beispiel eine Datei zu finden und deren Inhalt mit einer anderen Datei zu vergleichen:

$ find app -name 'one.php' 
/var/bar/app/one.php

$ diff /var/bar/app/one.php /var/bar/two.php

Sie könnten das tun:

$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.php

Die Zeichenfolge /var/bar/app/one.php befindet sich in der Zwischenablage, wenn Sie den ersten Befehl ausführen. 

Übrigens stehen pb in pbcopy und pbpaste für Pasteboard, ein Synonym für Zwischenablage. 

3
Raghu Dodda

Wie Konsolebox sagte, müsste man sich in Bash selbst hacken. hier ist ein recht gutes Beispiel dafür, wie man dies erreichen könnte. Das stderred-Repository (eigentlich zum Ausmalen von stdout gedacht) enthält Anweisungen zum Erstellen.

Ich habe es ausprobiert: Definieren eines neuen Dateideskriptors in .bashrc mögen

exec 41>/tmp/my_console_log

(Nummer ist beliebig) und ändere stderred.c dementsprechend, damit der Inhalt auch in fd 41 geschrieben wird. Es hat eine Art von funktioniert, enthält aber viele NUL-Bytes, seltsame Formatierungen und ist im Grunde genommen binäre Daten, nicht lesbar. Vielleicht könnte jemand mit guten Kenntnissen von C das ausprobieren.

Wenn ja, ist alles, was benötigt wird, um die letzte gedruckte Zeile zu erhalten, tail -n 1 [logfile].

2
Blauhirn

Ich habe eine Idee, die ich nicht sofort umsetzen kann. 

Was aber, wenn Sie so etwas wie das Folgende tun: 

$ MY_HISTORY_FILE = `get_temp_filename`
$ MY_HISTORY_FILE=$MY_HISTORY_FILE bash -i 2>&1 | tee $MY_HISTORY_FILE
$ some_command
$ cat $MY_HISTORY_FILE
$ # ^You'll want to filter that down in practice!

Möglicherweise gibt es Probleme mit der Pufferung von IO. Auch die Datei könnte zu groß werden. Man müsste eine Lösung für diese Probleme finden. 

0
William Navarre

Sie wissen nicht genau, wofür Sie dies benötigen, daher ist diese Antwort möglicherweise nicht relevant. Sie können die Ausgabe eines Befehls immer speichern: netstat >> output.txt, aber ich glaube nicht, dass Sie danach suchen.

Es gibt natürlich Programmiermöglichkeiten; Sie können einfach ein Programm zum Lesen der obigen Textdatei erhalten, nachdem der Befehl ausgeführt und mit einer Variablen verknüpft wurde. In Ruby, meiner bevorzugten Sprache, können Sie eine Variable außerhalb der Befehlsausgabe mithilfe von 'backticks' erstellen: 

output = `ls`                       #(this is a comment) create variable out of command

if output.include? "Downloads"      #if statement to see if command includes 'Downloads' folder
print "there appears to be a folder named downloads in this directory."
else
print "there is no directory called downloads in this file."
end

Stecken Sie dies in eine .rb-Datei und führen Sie es aus: Ruby file.rb und es wird eine Variable aus dem Befehl erstellt und Sie können sie bearbeiten. 

0
user4493605