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

1

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

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

A ideia é 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 liberação. A única solução em que pensei, mas extremamente undrY:

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

para todos os comandos . Como melhorar isso?

EDIT: Quero coletar a saída all para stdout e stderr e canalizá-la por meio de log() . Então, log() pode escolher desconsiderar tudo, registrar em um arquivo, imprimir, etc.

    
por Vorac 29.05.2018 / 17:53

2 respostas

0

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

Em segundo lugar, há (como é o caso do POSIX) uma infinidade de maneiras de fazer esse tipo de coisa. Eu provavelmente iria com algo como:

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

do_stuff | log

Mas você também pode:

(
    do_stuff
    do_more_stuff
) >> "$logfile"

Como para 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á-la "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
    
por 29.05.2018 / 18:02
0

Absolutamente nenhum resultado é simples, apenas redirecione o stdout e stderr para /dev/null :

do script
exec >/dev/null 2>&1

Isso afetará o próprio shell e quaisquer comandos executados posteriormente. Execute isso condicionalmente para escolher 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

Note que suprimir a saída all não é provavelmente uma boa ideia. É muito provável que o usuário queira uma notificação alguns para erros.

Se você insistir em passar a saída através da função (e estiver executando o 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 note que processar a saída com um loop de shell não é uma boa idéia, no mínimo é lento. Veja: Por que usar um loop de shell para processar texto é considerado uma prática ruim? . Se tudo o que você deseja é redirecionar um arquivo ou /dev/null , use apenas exec para configurar redirecionamentos.

    
por 29.05.2018 / 18:01