La respuesta aceptada no conserva STDERR como un descriptor de archivo separado. Eso significa
./script.sh >/dev/null
no saldrá bar
a la terminal, solo al archivo de registro, y
./script.sh 2>/dev/null
dará salida a ambos foo
y bar
al terminal. Claramente, ese no es el comportamiento que un usuario normal probablemente espera. Esto se puede solucionar mediante el uso de dos procesos tee separados, ambos anexados al mismo archivo de registro:
#!/bin/bash
# See (and upvote) the comment by JamesThomasMoon1979
# explaining the use of the -i option to tee.
exec > >(tee -ia foo.log)
exec 2> >(tee -ia foo.log >&2)
echo "foo"
echo "bar" >&2
(Tenga en cuenta que lo anterior no trunca inicialmente el archivo de registro; si desea ese comportamiento, debe agregar
>foo.log
al principio del guión)
La especificación POSIX.1-2008 detee(1)
requiere que la salida no esté almacenada, es decir, ni siquiera esté almacenada en línea, por lo que en este caso es posible que STDOUT y STDERR puedan terminar en la misma línea de foo.log
; sin embargo, eso también podría suceder en el terminal, por lo que el archivo de registro será un fiel reflejo de lo que se puede ver en el terminal, si no un espejo exacto del mismo. Si desea que las líneas STDOUT se separen limpiamente de las líneas STDERR, considere usar dos archivos de registro, posiblemente con prefijos de sello de fecha en cada línea para permitir el reensamblaje cronológico más adelante.