De acordo com este resposta SOF aceita:
In a pipeline, all commands run concurrently (with their stdout/stdin connected by pipes) so in different processes.
Portanto, embora as chaves por si só não criem uma sub-camada, o pipe faz isso (no bash); veja por exemplo.
#!/bin/bash
var=256
ps -u | grep $0
{
ps -u | grep $0
{
var="123"
export var
echo "var is "$var
ps -u | grep $0
} | tee log.txt
echo "var is "$var
}
echo "var is "$var
Então, o que queremos é evitar o pipe, enquanto ainda temos saída na tela e no arquivo de log.
Felizmente, o bash recebeu o recurso <(...)
para criar FIFOs temporários. O exemplo abaixo mostra uma possibilidade em que um ainda pode usar um bloco de código, transferir toda a sua saída para um log (aqui stdout
e stderr
são anexados a diferentes arquivos de log) e ter as variáveis alteradas acessíveis posteriormente, pois não em um subshell.
#!/bin/bash
VAR=123
echo "VAR first: $VAR"
{
VAR=256
echo "VAR in block: $VAR"
norealcommand
# show open files to see FIFOs
#lsof -p $$
date
otherbadcommand
}> >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
# dummy output to not mess up output order
echo | cat
#lsof -p $$
echo "VAR after block: $VAR"
cat -n stdout.log
cat -n stderr.log
que deve resultar em algo assim:
$ ./fifo /dev/shm |myself@mydesk|0|12:04:10
VAR first: 123
VAR in block: 256
./fifo: line 9: norealcommand: command not found
Mon Jul 3 12:04:37 CEST 2017
./fifo: line 13: otherbadcommand: command not found
VAR after block: 256
1 VAR in block: 256
2 Mon Jul 3 12:04:10 CEST 2017
3 VAR in block: 256
4 Mon Jul 3 12:04:37 CEST 2017
1 ./fifo: line 9: norealcommand: command not found
2 ./fifo: line 13: otherbadcommand: command not found
3 ./fifo: line 9: norealcommand: command not found
4 ./fifo: line 13: otherbadcommand: command not found
Espero que isso te faça feliz: -)