Salida del comando de bomba como argumento de función

Salida del comando de bomba como argumento de función

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 stdouty stderrcanalizarlo 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 $1en 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 stdouty stderra /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/nullsimplemente utilizarlo execpara configurar las redirecciones.

información relacionada