2>&1 >>outputfile | tee --append outputfile
Para um teste fácil:
echo -n >outputfile; bash -c "echo stdout >&1; echo stderr >&2" 2>&1 >>outputfile |
tee --append outputfile; echo "outputfile:"; cat outputfile
Editar 1:
Isto funciona escrevendo stdout (somente) para o arquivo, fazendo stdout de sterr para que ele passe pelo pipe, e tendo tee escreva sua saída para o mesmo arquivo.
As duas gravações devem ser feitas no modo de acréscimo ( >>
em vez de >
), caso contrário, ambas sobrescreveriam as outras saídas.
Como o pipe é um buffer, não há garantia de que a saída apareça no arquivo na ordem correta. Isso nem sequer mudaria se um aplicativo estivesse conectado a ambos os descritores de arquivo (dois canais). Para a ordem garantida, ambas as saídas teriam que passar pelo mesmo canal e ser marcadas respectivamente. Ou você precisaria de algumas coisas realmente extravagantes:
- Se stdout e stderr fossem redirecionados para um arquivo (não para o mesmo arquivo!) e os dois arquivos estivessem em um volume FUSE, o módulo FUSE poderia marcar cada gravação com um timestamp para que um segundo aplicativo pudesse classificar os dados corretamente e combiná-lo para o arquivo de saída real. Ou você não marca os dados, mas faz com que o módulo crie o arquivo de saída combinado. Muito provavelmente ainda não há nenhum módulo FUSE que faça isso ...
- A stdout e stderr podem ser direcionadas para
/dev/null
. As saídas do aplicativo seriam separadas, executando-o emstrace -f -s 32000 -e trace=write
. Você teria que inverter o escape nesse caso. Escusado será dizer que a aplicação não corre mais depressa ao ser rastreada. - Talvez o mesmo possa ser alcançado usando um módulo FUSE existente e simples e rastreando o módulo em vez do aplicativo. Isso pode ser mais rápido do que rastrear o aplicativo porque (ou melhor: se) o módulo provavelmente tem muito menos syscalls que o aplicativo.
- Se o aplicativo em si pode ser modificado: O aplicativo pode ser interrompido após cada saída (mas acho que isso é possível somente a partir do interior) e continuar somente depois de receber o sinal s (SIGUSR1 ou SIGCONT). A leitura do aplicativo do pipe teria que verificar o pipe e o arquivo quanto a novos dados e enviar o sinal após cada novo dado. Dependendo do tipo de aplicação, isso pode ser mais rápido ou mais lento que o método strace. FUSE seria a solução de velocidade máxima.