Como posso redirecionar a saída 'time' e a saída de comando para o mesmo pipe?

22

Suponha que eu tenha um binário chamado foo .

Se eu quiser redirecionar a saída de foo para algum outro processo bar , eu posso escrever ./foo | bar .

Por outro lado, se eu quisesse time foo e redirecionasse a saída de time eu poderia escrever, time (./foo) | bar .

A minha pergunta é: como posso colar a saída de time no final da saída de foo e canalizá-la através do mesmo canal ?

A solução a seguir é não o que estou procurando, porque inicia duas instâncias separadas do processo bar , enquanto eu quero um único canal compartilhado, para uma única instância de bar .

time (./foo | bar)  | bar

Para quem está curioso, a razão para não querer iniciar duas instâncias de bar é porque bar pode ser um cliente de rede e eu quero que as informações de tempo sejam enviadas para o servidor como parte do mesmo http POST message como a saída do processo.

    
por merlin2011 19.02.2014 / 20:56

3 respostas

26

Se eu entendi o que você está pedindo, isso vai funcionar. Estou usando os comandos ls ~ e tee como substitutos para ./foo e bar , mas a forma geral do que você quer é esta:

$ ( time ./foo ) |& bar

OBSERVAÇÃO: A saída de time já está sendo anexada no final de qualquer saída de ./foo , está sendo feita apenas no STDERR. Para redirecioná-lo através do tubo, você precisa combinar STDERR com STDOUT. Você pode usar |& ou 2>&1 para fazer isso.

$ ( time ./foo ) |& bar

-or-

$ ( time ./foo ) 2>&1 | bar

Exemplo

$ ( time ls . ) |&  tee cmd.log
cmd.log
file1
file2
file3
file4
file5

real    0m0.005s
user    0m0.000s
sys     0m0.001s

E aqui está o conteúdo do arquivo cmd.log produzido por tee .

$ more cmd.log 
cmd.log
file1
file2
file3
file4
file5

real    0m0.005s
user    0m0.000s
sys     0m0.001s
    
por 19.02.2014 / 21:14
9

time envia sua saída para stderr em vez de stdout por padrão. Você só precisa redirecionar para onde quiser.

Você diz "Por outro lado, se eu quisesse time foo e redirecionasse a saída de time eu poderia escrever, time (./foo) | bar ." mas isso está incorreto. Nesse caso, a saída do tempo ainda seria exibida no seu console, somente o stdout seria redirecionado.

Você pode redirecionar o stderr especificamente com:

(time foo) 2>&1 | bar

ou todos os canais com:

(time foo) |& bar

Os colchetes são necessários para que isso funcione corretamente.

    
por 19.02.2014 / 21:43
0

Descobri que isso funciona no Solaris. (time ls) &> file

    
por 23.01.2016 / 19:48