Maneira concisa de enviar para o arquivo se o argumento for fornecido, para stdout caso contrário

Maneira concisa de enviar para o arquivo se o argumento for fornecido, para stdout caso contrário

Gostaria que meu script fosse enviado para stdout, a menos que receba um nome de arquivo como argumento. Uma maneira óbvia é assim:

if [ -e "$1" ]; then
  command_with_output >$1
else
  command_with_output
fi

É bem feio e tem repetição, então gostaria de uma forma mais consciente de fazer isso.

Eu tentei o seguinte, mas não funciona.

[ -e "$1" ] && outfile=$1 || outfile='&1'
command_with_output >$outfile

Editar: isso não altera a relevância das respostas, mas percebi depois de fazer a pergunta que touch "$1" && outfile=$1é realmente o que preciso, pois [ -e "$1" ] && outfile=$1o arquivo pode ainda não existir e quero ter certeza de que posso escrever nele ou criar isso, não apenas que ele existe. Não estou mudando a pergunta porque isso colocaria as respostas fora de sincronia.

Responder1

execpode ser usado para redirecionar o stdout do script atual para outro arquivo.

[ -e "$1" ] && exec > $1
command_with_output

Responder2

Outra forma é usar $1como nome do arquivo se ele foi passado e /dev/stdoutcaso contrário (que é um link simbólico para /proc/self/fd/1no Linux e um nó de dispositivo com o mesmo significado em muitas outras variantes do Unix). Por exemplo, coloque isso no topo do script:

if [ -e "$1" ]; then
    filename=$1
else
    filename=/dev/stdout
fi

E então redirecione a saída de cada comando para$filename

Responder3

Se não for necessário nenhum parâmetro além de arquivo, isso também funcionará:

command_with_output > ${1:-/dev/stdout}

editar: Ou melhor ainda, já que você provavelmente também se preocupa com erros:

command_with_output &> ${1:-/dev/stdout}

informação relacionada