Eu faria como ...
#!/bin/sh -x
run() if ! ps -p "$run" >&2
then n=0 run=$$ exec "$0" "$@" 2>&1 | {
! tee outfile ; }
fi 2>/dev/null
run "$@" || exit
fn() { var=val$n; echo "$((n+=1)): $var"; }
fn
sleep 5
fn
IN
Isso primeiro verifica se ele já tem um canal aberto para um tee
em outro processo e, se não, o exec
s em um. Depois disso, toda a saída é canalizada para o restante do script, e todas as variáveis definidas entre elas e a saída do script são mantidas - o que é, de fato, como a verificação é feita em primeiro lugar.
Então, executando as impressões acima:
+ run
+ run
+ fn
+ var=val0
+ echo 1: val0
1: val0
+ sleep 5
+ fn
+ var=val1
+ echo 2: val1
2: val1
+ exit
E a execução de cat outfile
depois é impressa ...
+ run
+ run
+ fn
+ var=val0
+ echo 1: val0
1: val0
+ sleep 5
+ fn
+ var=val1
+ echo 2: val1
2: val1
+ exit
Você também pode considerar usar sed
em vez de tee
. Enquanto tee
terá mais desempenho para um caso todas as saídas , sed
pode gravar em muitos arquivos de uma só vez e pode fazê-lo condicionalmente.
Por exemplo, você pode fazer eco de uma linha como:
echo 'LOG-ONLY: some message here'
E um processo de sed
de audição poderia ser feito:
sed -n '/^LOG-ONLY:/!p;s///w ./my_log.txt'
... o que seria w
desta linha para um arquivo depois de remover a parte LOG_ONLY
e evitar imprimi-la no terminal.