Estou tentando modificar um script que usa o seguinte:
# first portion of script
# ...
exec > >(tee -ia $OUT)
# ...
# second portion of script
O problema que tenho com este script é que ele produz uma saída volumosa para stdout
(meu terminal). O autor do script não incluiu opções para eliminar a saída do terminal. Gostaria de adicionar uma opção que remova o stdout
e obtenha a saída somente no arquivo $OUT
.
Aqui está o que eu tentei:
TERM_OPT="OFF"
# first portion of script
# ...
if [ $TERM_OPT != "OFF" ]; then
exec > >(tee -ia $OUT)
else {
# ...
# second portion of script
} > $OUT
fi
Isso parece funcionar, mas não tenho certeza sobre o uso de chaves {}
neste contexto, pois a seção GNU de Comandos de agrupamento ( parece ) afirma que ;
é necessário um ponto-e-vírgula após a lista. Mas adicionar ;
ou deixar de lado parece não fazer diferença. Eu me perguntei se deveria usar parênteses ()
em vez de chaves, mas isso faz com que tudo dentro do ()
seja executado em um subshell. Não estou particularmente interessado nisso, pois é o script de outra pessoa e as implicações do subshell não são claras para mim (não tentei isso).
A outra coisa que tentei parecia um hack, mas li sobre outras pessoas que o usaram e parece funcionar bem também:
TERM_OPT="OFF"
# first portion of script
# ...
if [ $TERM_OPT != "OFF" ]; then
exec > >(tee -ia $OUT)
else
exec > >(tee -ia $OUT 1> /dev/null)
fi
# ...
# second portion of script
Eu gosto disso porque parece mais independente , mas isso não é uma consideração importante AFAICT.
Portanto, a questão é: Qual é a maneira correta de fazer isso? Com isso, quero dizer qual é a maneira correta de cancelar a saída do terminal após um exec > >(tee -ia $OUT)
? Uma dessas soluções é preferível à outra - ou preciso fazer algo completamente diferente?
Apenas redirecionar para o
$OUT
arquivo noa
modo ppend é muito mais fácil:Cuidado, o shell não espera
tee
ao sair, então você pode descobrir quetee
ainda está gerando algo após a conclusão do script.Veja como
A
foi a saída após B.Para contornar isso, você pode adicionar:
No final do roteiro ou em uma
EXIT
armadilha.Outra opção (que também funcionaria em sh) é colocar todo o seu script dentro de uma
main
função e fazer:Se você deseja redirecionar o stdout para ser anexado a um arquivo, e também não ter uma cópia da saída no terminal, basta fazer:
O único propósito
tee
é duplicar um fluxo em vários, portanto, se você deseja a saída apenas em um local, não há necessidade disso. É claro que vocêtee -ia "$OUT" > /dev/null
também funcionaria, mas isso é um pouco bobo: você ainda estaria duplicando a saída, apenas para descartar a outra cópia.As chaves requerem um ponto e vírgula ou uma nova linha. Na verdade, diz isso no manual: "O ponto e vírgula (ou nova linha) da lista a seguir é obrigatório." Os parênteses não exigem nenhum dos dois.
As implicações de um subshell são que o subshell é executado em uma cópia independente do shell e quaisquer alterações no subshell não são visíveis fora dele. Se o script terminar de qualquer maneira quando o subshell terminar, isso não significa muito, e tudo o que o subshell faz é iniciar um processo desnecessário.
Eu iria com algo como