Se você quiser redirecionar globalmente tudo o que está escrito (como você faz agora), é complicado, mas pode ser hackeado em conjunto.
Eu recomendo strongmente que, se for possível, basta fazê-lo por tubulação normal. apenas embrulhe tudo que você faz em um subnível. Neste caso,
(
echo "this is the message"
other stuff
) | cat
ou apenas escreva tudo em uma variável com a sintaxe "$ ()".
A próxima maneira é usar o que você fez, mas escreva para um tmpfs ou /dev/shm
se eles estiverem disponíveis. Isso é muito simples, mas você precisa saber quais sistemas de arquivos baseados em RAM estão instalados (e configurá-los, se possível).
Outra maneira é criar um fifo com mkfifo
. Em ambos os casos, você precisa limpar a si mesmo.
EDITAR:
Eu tenho um hack muito feio, mas aposto que alguém pode melhorar isso.
#!/bin/bash
exec 3>&1
exec > >( tee >( ( tac && echo _ ) | tac | (read && cat > ./log) ) )
echo "lol"
sleep 5
echo "lol"
echo "finished writing"
exec >&-
exec >&3
exec 3>&-
echo "stdout now reopen"
sleep 1 #wait if the file is still being written asynchronously
cat ./log
Como funciona: primeiro, você tem um tee
para poder ver o que está acontecendo. Isso, por sua vez, resulta em outra substituição de processo. Lá, você tem o truque tac|tac
que (porque tac
precisa de toda a entrada para iniciar a saída) espera que todo o fluxo termine antes de continuar. A última parte está em um subshell que realmente gera isso em um arquivo. É claro que o shell final, imediatamente após a instanciação, criaria o arquivo de saída no sistema de arquivos se essa fosse a única linha. Então, algo que também espera que a entrada finalmente chegue, precisa ser feito primeiro, para atrasar a criação do arquivo. Eu faço isso enviando uma linha fictícia primeiro com echo e, em seguida, lendo e descartando-a. O read
bloqueia até você fechar o descritor de arquivo, sinalizando para tac
sua hora chegou. Portanto, o fechamento do descritor de arquivo stdout no final. Eu também salvei o stdout
original antes de abrir a substituição do processo, para restaurá-lo no final (para usar cat
mais uma vez). Há um sleep 5
lá, então eu poderia verificar com ls
se o arquivo realmente não foi criado muito cedo. O sono final é mais complicado ... O subshell é assíncrono e, se houver muita saída, você está aguardando que ambos os tac
s façam suas tarefas antes que o arquivo esteja realmente lá. Então, razoavelmente, você provavelmente precisará fazer outra coisa para verificar se a coisa está realmente terminada. Por exemplo, && touch sentinel
no final do último subshell e while [ ! -f sentinel ]; do sleep 1; done && rm sentinel
antes de você finalmente usar o arquivo.
Ao todo, duas substituições de processo e no interior uma duas sub-caixas e dois tubos. É uma das coisas mais feias que já escrevi ... mas deve criar o arquivo apenas quando você fechar o stdout, o que significa que ele é bem controlado e pode ser feito quando os sistemas de arquivos estiverem prontos.