Como redirecionar a saída `time 'e comandar a saída para o mesmo canal?

24

Suponha que eu tenha um binário chamado foo.

Se eu quiser redirecionar a saída de foopara outro processo bar, eu poderia escrever ./foo | bar.

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

Minha pergunta é: como posso colar a saída timeno final da saída fooe canalizá-la pelo mesmo tubo ?

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 pipe compartilhado, para uma única instância de bar.

time (./foo | bar)  | bar

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

merlin2011
fonte
respondidas aqui, a resposta um pouco melhor: stackoverflow.com/questions/13356628/...
JDS

Respostas:

29

Se eu entender o que você está pedindo, eu farei. Estou usando os comandos ls ~e teecomo substitutos de ./fooe bar, mas a forma geral do que você deseja é esta:

$ ( time ./foo ) |& bar

NOTA: A saída de timejá está sendo anexada no final de qualquer saída de ./foo, apenas está sendo feita no STDERR. Para redirecioná-lo através do canal, você precisa combinar STDERR com STDOUT. Você pode usar um |&ou 2>&1para fazê-lo.

$ ( 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.logproduzido por tee.

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

real    0m0.005s
user    0m0.000s
sys     0m0.001s
slm
fonte
Observe que essa sintaxe não funciona para o BASH.
Jvriesem
11
@jvriesem todos os exemplos são de bash
slm
9

timeenvia 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 timefoo, e redirecionar a saída, timeeu poderia escrever time (./foo) | bar". mas isso está realmente incorreto. Nesse caso, a saída de tempo ainda seria exibida no seu console, apenas o stdout seria redirecionado.

Você pode redirecionar o stderr especificamente com:

(time foo) 2>&1 | bar

ou todos os tubos com:

(time foo) |& bar

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

Tumulto
fonte
0

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

anisbet
fonte
11
Isso não é diferente de qualquer uma das soluções existentes
roaima