Saída do comando da bomba como argumento de função

Saída do comando da bomba como argumento de função

Eu tenho esta função extremamente simples no meu script:

# Used for debug tracing.
log()
{
    :
    echo "log: $1"
}

A ideia é poder personalizar/desativar o registro em um único local. Muito bruto.

Agora quero que meu script não produza absolutamente nenhuma saída quando estiver na configuração de lançamento. A única solução que pensei, mas extremamente suja:

TMPFILE='/tmp/tempfilewithpossiblyuniquename'
cmd 1>"$TMPFILE" 2>"$TMPFILE"
cat "$TMPFILE" | xargs log
rm "$TMPFILE"

paracada comando. Como melhorar isso?


EDIT: quero coletartodossaída para stdoute stderre canalizá-lo através de log(). Depois log()pode optar por desconsiderar tudo, registrar em um arquivo, imprimir etc.

Responder1

Primeiramente, essa função registrará apenas a primeira "palavra" de qualquer coisa enviada a ela, já que você usa $1em vez de "$*".

Em segundo lugar, existem (como é frequentemente o caso do POSIX) inúmeras maneiras de fazer esse tipo de coisa. Eu provavelmente escolheria algo como:

log() {
    cat - >> "$logfile"
}

do_stuff | log

Mas você também pode:

(
    do_stuff
    do_more_stuff
) >> "$logfile"

Quanto a suprimir completamente toda a saída - isso é algo que geralmente é melhor deixar para o ambiente de chamada (por exemplo ./thing 1> /dev/null 2> &1), em vez de bloqueá-lo "no código", por assim dizer. Dito isto:

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

Responder2

Absolutamente nenhuma saída é simples, apenas redirecione o script stdoute stderrpara /dev/null:

exec >/dev/null 2>&1

Isso afetará o próprio shell e quaisquer comandos que ele executar posteriormente. Execute isso condicionalmente para escolher para onde a saída será redirecionada.

if [ "$output_to_file" = 1 ]; then
    exec > "$outputfilename" 2>&1
elif [ "$output_suppress" = 1 ]; then
    exec > /dev/null 2>&1
fi

Observe que a supressãotodosa saída provavelmente não é uma boa ideia. É muito provável que o usuário queiraalgunsnotificação de erros.


Se você insistir em passar a saída pela função (e estiver executando Bash/ksh/Zsh), poderá usar a substituição de processo:

#!/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

Embora observe que processar a saída com um shell loop não é uma ideia muito boa, no mínimo é lento. Ver:Por que usar um loop de shell para processar texto é considerado uma prática inadequada?. Se tudo que você deseja é redirecionar um arquivo, ou para /dev/null, basta usar execpara configurar redirecionamentos.

informação relacionada