Direkte Ausgabe eines Befehls in eine Datei mit dem ursprünglichen Befehl UND Drucken im Terminal

8

Wenn ich einige Tests ausführe, muss ich eine Reihe von Befehlen ausführen. Es wäre äußerst nützlich für mich und würde mir viel Zeit sparen, wenn es eine Möglichkeit gäbe, all diese Dinge zu tun:

  • Führen Sie den Befehl aus, den ich ausführen muss
  • Leiten Sie die gesamte Ausgabe des Befehls in eine angegebene Datei um
  • Fügen Sie den ursprünglichen Befehl in die angegebene Datei ein
  • Drucken Sie die Ausgabe des ursprünglichen Befehls im Terminal

Die Leute haben mir vorgeschlagen, Tee zu verwenden, das sowohl zum Drucken auf dem Terminal als auch zum Senden an eine Datei hervorragend geeignet ist, aber den ursprünglichen Befehl nicht enthält. Am Ende möchte ich eine Datei haben, in der die erste Zeile der Befehl ist, den ich ausgeführt habe, und darunter die Ausgabe des Befehls.

Jemand schlug dies vor:

echo "ls -l" | xargs -I{} bash -c "echo >> output.file; eval {} >> output.file"

Dadurch wird jedoch weder die Ausgabe im Terminal gedruckt noch der ursprüngliche Befehl in die Datei aufgenommen.

Ich würde mich über Ideen freuen.

Shaneoh
quelle
2
Fast ein Duplikat von askubuntu.com/q/688498/295286 .
Sergiy Kolodyazhnyy
Ich habe dies bei meiner Suche nicht gefunden - nicht genau das gleiche, hätte mich aber wahrscheinlich zur Antwort geführt.
Shaneoh
Ja, und deshalb habe ich fast das Duplikat gesagt . Aber um ganz ehrlich zu sein, können Sie von dort fast jede Lösung nehmen und sie mit Rohrleitungen verwenden tee.
Sergiy Kolodyazhnyy

Antworten:

14

Das teesuchen Sie.

ls -l | tee outfile

druckt die Ausgabe von ls -lan stdout (dh das Terminal) und speichert sie gleichzeitig in der Datei outfile. Aber : Der Befehlsname wird weder in stdout noch in die Datei geschrieben. Um dies zu erreichen, geben Sie einfach echoden Befehlsnamen ein, bevor Sie den Befehl ausführen, und leiten Sie beide Ausgaben an tee:

( echo "ls -l" && ls -l ) | tee outfile

Die Eingabe ist umständlich. Warum also nicht eine Funktion definieren?

both(){ ( echo "$@" && "$@" ) | tee outfile ;}

Danach können Sie einfach laufen

both ls -l

um das gewünschte Ergebnis zu erhalten. Fügen Sie die Funktion in Ihr ein ~/.bashrc, damit sie in jedem neuen Terminal definiert wird.

Wenn Sie in der Lage sein möchten, die Ausgabedatei als erstes Argument wie in anzugeben

both output ls -l

mach es stattdessen:

both(){ ( echo "${@:2}" && "${@:2}" ) | tee "$1" ;}

Wenn Sie nicht möchten, dass die Ausgabedatei überschrieben, sondern an sie angehängt wird, fügen Sie die -aOption hinzu tee.

Dessert
quelle
9

Sie können den scriptBefehl verwenden, mit dem eine Typoskriptdatei von allem erstellt wird, was auf Ihrem Terminal gedruckt wird. Es erstellt eine gegabelte Muschel und zeichnet alles auf, bis diese Muschel verlassen wird.

$ script my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
Script done on Tue 28 Nov 2017 09:46:27 AM UTC

Wenn ich cat my_outputdann die gleiche Ausgabe bekomme:

$ cat my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
exit

Script done on Tue 28 Nov 2017 09:46:27 AM UTC
AJefferiss
quelle
6

Sie können die Debugging-Funktion der Shell zusammen mit teefolgenden Funktionen verwenden :

( set -x; command1 args...; command2 args ) 2>&1 | tee output.log
  • ( ... )Startet eine Sub-Shell, mit der Sie die Ausgabestreams aller in der Sub-Shell ausgeführten Befehle „sammeln“ können. Es enthält auch die Auswirkung des folgenden setBefehls auf diese Unter-Shell.

  • set -xAktiviert die xShell-Option, die alle Befehle, die die Shell ausführt, in den Standardfehlerstrom druckt, bevor sie ausgeführt werden.

  • 2>&1 leitet Stream 2 (Standardfehler) zu Stream 1 (Standardausgabe) um.

  • | Leitet den Standardausgabestream des linken Befehls zum Standardeingabestream des rechten Befehls um.

  • tee FILEkopiert den Standardeingabestream in die Datei FILEund in die Standardausgabe.

Wenn sich Ihre Befehlssequenz bereits in einer Skriptdatei befindet, ist es sinnvoller, sie wie folgt auszuführen:

bash -x /path/to/script args... 2>&1 | tee output.log
David Foerster
quelle