
Tengo esta función extremadamente simple en mi script:
# Used for debug tracing.
log()
{
:
echo "log: $1"
}
La idea es poder personalizar/desactivar el registro en un solo lugar. Muy crudo.
Ahora quiero que mi script no produzca absolutamente ningún resultado cuando esté en la configuración de lanzamiento. La única solución que he pensado, pero extremadamente seca:
TMPFILE='/tmp/tempfilewithpossiblyuniquename'
cmd 1>"$TMPFILE" 2>"$TMPFILE"
cat "$TMPFILE" | xargs log
rm "$TMPFILE"
paracada comando. ¿Cómo mejorar esto?
EDITAR: quiero coleccionartodosalida hacia stdout
y stderr
canalizarlo a través de log()
. Luego log()
puede optar por ignorar todo, iniciar sesión en un archivo, imprimir, etc.
Respuesta1
En primer lugar, esa función solo registrará la primera "palabra" de cualquier cosa que se le envíe, ya que usa $1
en lugar de "$*"
.
En segundo lugar, existen (como suele ser el caso con POSIX) innumerables formas de hacer este tipo de cosas. Probablemente elegiría algo como:
log() {
cat - >> "$logfile"
}
do_stuff | log
Pero también podrías:
(
do_stuff
do_more_stuff
) >> "$logfile"
En cuanto a suprimir completamente toda la salida, eso es algo que generalmente es mejor dejar para el entorno de invocación (por ejemplo ./thing 1> /dev/null 2> &1
), en lugar de bloquearlo "en código", por así decirlo. Dicho eso:
squashout="true" # comment this out to stop killing output
if ! [[ "true" = "${squashout-false}" ]]; then
# Redirect stdout and stderr to the null device.
exec 1> /dev/null
exec 2> /dev/null
fi
Respuesta2
Absolutamente ningún resultado es simple, simplemente redirija el script stdout
y stderr
a /dev/null
:
exec >/dev/null 2>&1
Eso afectará al propio shell y a cualquier comando que ejecute posteriormente. Ejecútelo condicionalmente para elegir dónde se redirige la salida.
if [ "$output_to_file" = 1 ]; then
exec > "$outputfilename" 2>&1
elif [ "$output_suppress" = 1 ]; then
exec > /dev/null 2>&1
fi
Tenga en cuenta que suprimirtodoLa salida probablemente no sea una buena idea. Es muy probable que el usuario quieraalgunonotificación de errores.
Si insistes en pasar la salida a través de la función (y estás ejecutando Bash/ksh/Zsh), puedes usar la sustitución de procesos:
#!/bin/bash
mangle_output() {
# do something smarter here
while read -r line; do
echo "output: $line";
done;
}
# redirect stdout and stderr to the function
exec > >(mangle_output) 2>&1
echo something that produces output
Aunque tenga en cuenta que procesar la salida con un bucle de shell no es una muy buena idea, al menos es lento. Ver:¿Por qué se considera una mala práctica utilizar un bucle de shell para procesar texto?. Si todo lo que desea es redirigir un archivo, o /dev/null
simplemente utilizarlo exec
para configurar las redirecciones.