Como usar o tee para capturar STDOUT de um bloco de código para um nome de arquivo definido dentro do bloco?

3

Eu quero enviar STDOUT para um bloco de script para um arquivo cujo nome é definido por uma variável dentro do bloco. No entanto, quando eu uso tee , parece que a variável fora do bloco não existe mais. Sem tee , a variável ainda existe.

Script:

#!/bin/bash
{
    log="mylog.txt"
    echo log: $log
} |tee $log

echo log: $log

Resultado:

log: mylog.txt
log:

e nenhum arquivo mylog.txt produzido por tee .

    
por Sébastien Clément 09.01.2015 / 20:04

2 respostas

3

 #!/bin/bash
 log="mylog.txt"
 {
     echo log: $log
 } |tee $log

O pipeline faz com que a lista de comandos seja executada em um sub-shell. Como a variável estava em um sub-shell diferente, isso não pôde ser comunicado. Assim, você tem que mover a variável para um contexto comum para ser usado corretamente.

    
por 09.01.2015 / 21:55
0

Um pipe nomeado pode funcionar para você. Com apenas um pouco mais de trabalho, você pode obtê-lo de forma robusta e sem ter que configurar trap s ou similar para lidar com a limpeza do sistema de arquivos depois - basta fazer a limpeza antecipadamente.

pipe=/tmp/$$pipe log=mylog.txt
mkfifo "$pipe"; exec 3<>"$pipe"
{ rm "$pipe"; tee "$log"; } <&3 >/dev/tty &
pipe=$!; exec >&3 3>&-

Lá. A partir deste momento, toda a saída do script está sendo gravada em um canal nomeado (usado para ser) que está sendo lido por um processo tee de base reversa. O arquivo especial do pipe nomeado já foi removido do sistema de arquivos e, portanto, ele não precisa ser limpo mais tarde e as únicas referências a ele que permanecem são os descritores de arquivo atribuídos ao stdout e tee do seu script stdin .

Dito isso, convém configurar pelo menos um trap :

trap "kill PIPE $pipe" 0

... apenas para garantir que tee não fique em segundo plano após o script sair.

Se você se deparar com problemas de buffer - o que não deve ser um problema, eu acho, já que tee tem uma linha aberta em /dev/tty - você pode tentar sua sorte chamando tee via stdbuf . A página stdbuf man especifica especificamente as suas apostas, onde tee está interessado - nota tee como uma aplicação que provavelmente reajustará seus próprios buffers após a invocação - mas é mais positiva sobre a interação do que é para dd de qualquer maneira.

    
por 12.01.2015 / 00:10