如何将“时间”输出和命令输出重定向到同一管道?


24

假设我有一个名为的二进制文件foo

如果我想将输出重定向foo到其他进程bar,我可以写./foo | bar

另一方面,如果我想对timefoo进行重定向,然后重定向其输出,则time可以编写time (./foo) | bar

我的问题是,我如何将输出的内容粘贴到输出time的末尾foo并通过同一管道传输?

以下解决方案不是我想要的解决方案,因为它启动了流程的两个单独实例bar,而我希望将单个共享管道连接到的单个实例bar

time (./foo | bar)  | bar

对于任何好奇的人,不想启动两个实例的bar原因是因为它bar可以是网络客户端,所以我希望将定时信息http POST作为与过程输出相同的消息的一部分发送到服务器。


在这里回答,更好的答案:stackoverflow.com/questions/13356628/…–
JDS

Answers:


29

如果我了解您的要求,那么就可以了。我使用的命令ls ~tee作为替身./foobar,但你想要的是这种一般形式:

$ ( time ./foo ) |& bar

注意:的输出time已经被附加到的任何输出的末尾./foo,它只是在STDERR上完成的。要通过管道重定向它,您需要将STDERR与STDOUT结合使用。您可以使用|&2>&1这样做。

$ ( time ./foo ) |& bar

-or-

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

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

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

这是cmd.log产生的文件的内容tee

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

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

请注意,此语法不适用于BASH。
jvriesem

1
@jvriesem所有示例均来自bash
slm

9

time默认情况下,将其输出发送到stderr而不是stdout。您只需要将其重定向到所需的位置即可。

您说:“另一方面,如果我想对timefoo进行重定向,然后重定向time我可以写的输出,” time (./foo) | bar但这实际上是不正确的。在这种情况下,时间的输出仍将显示在您的控制台上,仅标准输出将被重定向。

您可以使用以下方法专门重定向stderr:

(time foo) 2>&1 | bar

或所有具有以下功能的管道:

(time foo) |& bar

需要使用括号才能使其正常工作。


0

我发现这在Solaris上有效。 (time ls) &> file


1
这与任何现有解决方案都没什么不同
roaima
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.