Para fines de documentación, me refiero a redirigir al archivo stdout y stderr desde un comando que ejecuto.
Por ejemplo, ejecutaría (mi comando es menos trivial que el alias ll
pero probablemente no importe):
$ 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
...
También con fines de documentación, quiero almacenar en el mismo archivo de salida la línea de comando que utilicé.
El comportamiento y la salida previstos son
$ [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
...
¿Cómo se puede hacer esto?
Sé que podría escribir un script bash y ejecutarlo, por lo que el comando permanecería documentado por separado.
Podría escribir un script para hacer eco de la línea de comando en el archivo y luego ejecutarlo con redirección al mismo archivo.
Estoy buscando una posible solución sin secuencias de comandos.
EDITAR :
Comentarios sobre una buena respuesta.
Esto no encajaría como comentario.
Probé con el comando echo_command ll echo_command.sh ../dir > out-err.dat 2>&1
.
Guión echo_command.sh
, que yo source
, contiene las definiciones de las funciones.
../dir
es un directorio inexistente, para forzar alguna salida a stderr
.
Método 1 :
Funciona bien, excepto por dos problemas:
-
No entiende de alias (
ll
en este caso; al reemplazar conls
funcionó). -
No registra la parte de redirección.
Método 2 :
No funciona tan bien. Ahora también se imprime la parte de redirección, pero la línea de comando se imprime en la pantalla en lugar de redirigir al archivo.
EDITAR :
Comentarios sobre un comentario publicado, sobre un script
utilidad.
Es bastante versátil, más aún con scriptreplay
.
script
se puede llamar solo, lo que produce un shell interactivo (no mantendría el historial reciente del shell principal)
También se puede llamar como script -c <command> <logfile>
. Esta última forma se corresponde con el objetivo del OP, pero no almacena el comando en sí mismo en el archivo de registro. Produce (al menos en los casos básicos) el mismo resultado que <command> > <logfile> 2>&1
.
Así que parece que esto no es útil aquí.
Respuesta aceptada:
Podrías usar una función como esta:
echo_command() { printf '%sn' "${*}"; "${@}"; }
Ejemplo:
$ echo_command echo foo bar baz
echo foo bar baz
foo bar baz
$ echo_command uname
uname
Linux
Como dijo Tim Kennedy, también hay un script
muy útil 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
Actualizar
Si también necesita registrar las redirecciones y básicamente cada sintaxis de shell (tenga en cuenta que agregué un poco de Command line:
mensaje para identificar fácilmente el comando que se está ejecutando):
echo_command() {
local arg
for arg; do
printf 'Command line: %sn' "${arg}"
eval "${arg}"
done
}
Solo tenga en cuenta que debe tener mucho cuidado con las comillas como eval
se usa:
$ echo_command 'echo foo > "file 2"; cat "file 2"'
Command line: echo foo > "file 2"; cat "file 2"
foo
También acepta muchos comandos a la vez en lugar de 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