A scopo di documentazione, intendo reindirizzare al file stdout e stderr da un comando che eseguo.
Ad esempio, eseguirei (il mio comando è meno banale dell'alias ll
ma probabilmente non importa):
$ 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
...
Anche per scopi di documentazione, voglio memorizzare nello stesso file di output la riga di comando che ho usato.
Il comportamento e l'output previsti sono
$ [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
...
Come si può fare?
So che potrei scrivere uno script bash ed eseguirlo, quindi il comando rimarrebbe documentato separatamente.
Potrei inoltre scrivere uno script per fare eco alla riga di comando su file e quindi eseguirlo reindirizzando allo stesso file.
Sto cercando una possibile soluzione senza script.
MODIFICA :
Feedback su una bella risposta.
Questo non si adatterebbe come commento.
Ho provato con il comando echo_command ll echo_command.sh ../dir > out-err.dat 2>&1
.
Script echo_command.sh
, che io source
, contiene le definizioni delle funzioni.
../dir
è una directory inesistente, per forzare un output su stderr
.
Metodo 1 :
Funziona bene, ad eccezione di due problemi:
-
Non comprende gli alias (
ll
in questo caso; durante la sostituzione conls
ha funzionato). -
Non registra la parte di reindirizzamento.
Metodo 2 :
Non funziona molto bene. Ora viene stampata anche la parte di reindirizzamento, ma la riga di comando viene stampata sullo schermo anziché reindirizzata su file.
MODIFICA :
Feedback su un commento pubblicato, su uno script
utility.
È abbastanza versatile, a maggior ragione con scriptreplay
.
script
può essere chiamato da solo, che produce una shell interattiva (non manterrebbe la cronologia recente della shell madre)
Può anche essere chiamato come script -c <command> <logfile>
. Quest'ultimo modulo corrisponde all'obiettivo dell'OP, ma non memorizza il comando stesso nel file di registro. Produce (almeno nei casi base) lo stesso output di <command> > <logfile> 2>&1
.
Quindi sembra che questo non sia utile qui.
Risposta accettata:
Potresti usare una funzione come questa:
echo_command() { printf '%sn' "${*}"; "${@}"; }
Esempio:
$ echo_command echo foo bar baz
echo foo bar baz
foo bar baz
$ echo_command uname
uname
Linux
Come ha detto Tim Kennedy, c'è anche uno script
molto utile comando:
$ 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
Aggiorna
Se hai anche bisogno di registrare i reindirizzamenti e praticamente ogni sintassi della shell (nota che ho aggiunto una piccola Command line:
messaggio per identificare facilmente il comando in esecuzione):
echo_command() {
local arg
for arg; do
printf 'Command line: %sn' "${arg}"
eval "${arg}"
done
}
Tieni solo in considerazione che dovresti stare molto attento con le virgolette come eval
viene utilizzato:
$ echo_command 'echo foo > "file 2"; cat "file 2"'
Command line: echo foo > "file 2"; cat "file 2"
foo
Accetta anche molti comandi contemporaneamente invece di uno solo:
$ echo_command 'echo foo' 'echo bar' 'echo baz'
Command line: echo foo
foo
Command line: echo bar
bar
Command line: echo baz
baz