Zu Dokumentationszwecken möchte ich von einem Befehl, den ich ausführe, auf die Datei stdout und stderr umleiten.
Zum Beispiel würde ich ausführen (mein Befehl ist weniger trivial als der Alias ll
aber es spielt wahrscheinlich keine Rolle):
$ ll > out-err.dat 2>&1
$ cat out-err.dat
drwxr-xr-x 39 us00001 us00001 4096 jul 31 14:57 ./
drwxr-xr-x 3 root root 4096 feb 2 06:06 ../
-rw------- 1 us00001 us00001 62226 jul 31 11:56 .bash_history
...
Auch zu Dokumentationszwecken möchte ich die von mir verwendete Befehlszeile in derselben Ausgabedatei speichern.
Das beabsichtigte Verhalten und die Ausgabe sind
$ [NEW COMMAND LINE]?
$ cat out-err.dat
[NEW COMMAND LINE] <- This first line would contain the command line used
drwxr-xr-x 39 us00001 us00001 4096 jul 31 14:57 ./
drwxr-xr-x 3 root root 4096 feb 2 06:06 ../
-rw------- 1 us00001 us00001 62226 jul 31 11:56 .bash_history
...
Wie kann das gemacht werden?
Ich weiß, dass ich ein Bash-Skript schreiben und ausführen könnte, sodass der Befehl separat dokumentiert bleiben würde.
Ich könnte außerdem ein Skript schreiben, um die Befehlszeile in eine Datei zu übertragen, und es dann mit einer Umleitung dorthin ausführen file.
Ich suche nach einer möglichen skriptlosen Lösung.
BEARBEITEN :
Feedback zu einer netten Antwort.
Das würde nicht als Kommentar passen.
Ich habe mit dem Befehl echo_command ll echo_command.sh ../dir > out-err.dat 2>&1
getestet .
Skript echo_command.sh
, die ich source
, enthält die Definitionen der Funktionen.
../dir
ein nicht existierendes Verzeichnis ist, um eine Ausgabe an stderr
zu erzwingen .
Methode 1 :
Funktioniert gut, bis auf zwei Probleme:
-
Es versteht keine Aliase (
ll
in diesem Fall; beim Ersetzen durchls
es hat funktioniert). -
Der Umleitungsteil wird nicht aufgezeichnet.
Methode 2 :
Es funktioniert nicht so gut. Jetzt wird auch der Umleitungsteil gedruckt, aber die Befehlszeile wird auf den Bildschirm gedruckt, anstatt in die Datei umgeleitet zu werden.
BEARBEITEN :
Feedback zu einem geposteten Kommentar zu einem script
Dienstprogramm.
Es ist ziemlich vielseitig, noch mehr mit scriptreplay
.
script
kann allein aufgerufen werden, was eine interaktive Shell erzeugt (es würde nicht die aktuelle Geschichte der Eltern-Shell behalten)
Es kann auch als script -c <command> <logfile>
aufgerufen werden . Diese letzte Form entspricht dem Ziel des OP, speichert den Befehl selbst jedoch nicht in der Protokolldatei. Es erzeugt (zumindest in Basisfällen) dieselbe Ausgabe wie <command> > <logfile> 2>&1
.
Es scheint also, dass dies hier nicht nützlich ist.
Akzeptierte Antwort:
Sie könnten eine Funktion wie diese verwenden:
echo_command() { printf '%sn' "${*}"; "${@}"; }
Beispiel:
$ echo_command echo foo bar baz
echo foo bar baz
foo bar baz
$ echo_command uname
uname
Linux
Wie Tim Kennedy sagte, gibt es auch ein sehr nützliches script
Befehl:
$ script session.log
Script started, file is session.log
$ echo foo
foo
$ echo bar
bar
$ echo baz
baz
$ exit
exit
Script done, file is session.log
$ cat session.log
Script started on 2018-07-31 16:30:31-0500
$ echo foo
foo
$ echo bar
bar
$ echo baz
baz
$ exit
exit
Script done on 2018-07-31 16:30:43-0500
Aktualisieren
Wenn Sie auch die Umleitungen und im Grunde jede Shell-Syntax protokollieren müssen (beachten Sie, dass ich eine kleine Command line:
Meldung zur einfachen Identifizierung des ausgeführten Befehls):
echo_command() {
local arg
for arg; do
printf 'Command line: %sn' "${arg}"
eval "${arg}"
done
}
Beachten Sie nur, dass Sie mit dem Zitieren als eval
sehr vorsichtig sein sollten wird verwendet:
$ echo_command 'echo foo > "file 2"; cat "file 2"'
Command line: echo foo > "file 2"; cat "file 2"
foo
Es akzeptiert auch viele Befehle auf einmal statt nur einem:
$ echo_command 'echo foo' 'echo bar' 'echo baz'
Command line: echo foo
foo
Command line: echo bar
bar
Command line: echo baz
baz