将时间输出存储在变量中

时间:2015-03-02 19:30:10

标签: bash

我有以下命令行:

time `while [ $i -lt 200000 ]; do i=$[$i+1]; done` | grep "real"

根据我所知的bash,这应该首先给我while循环的运行时间并将其用作grep命令的输入,然后grep命令应该只打印出真实的time命令给出的时间,而是打印time命令的完整输出

那么为什么它没有像我期望的那样工作。还有更好的方法吗?

3 个答案:

答案 0 :(得分:3)

bash-builtin time命令在bash中有点特殊。事实上,它被归类为关键字(尝试运行type time)。

它在stderr上输出它的输出,但通过一些魔法bash类型的“加注”输出到其包含的管道之外,所以即使你通过管道从命令管道stderr,它也无法通过。

您需要做的是将time命令包围在支撑块中(这会导致time的输出成为块的stderr流的一部分),将块的stderr重定向到管道,然后你将获得time输出:

{ time while [ $i -lt 200000 ]; do i=$[$i+1]; done; } 2>&1| grep real;

答案 1 :(得分:2)

您需要从time

捕获stderr
$ i=0; { time while [ "$i" -lt 200000 ]; do i=$[$i+1]; done; } 2>&1 | grep "real"
real    0m2.799s

讨论

shell关键字time在整个管道上运行,并在stderr上报告时间信息。要捕获该输出,必须将time放入组{...;}或子shell,(...)中,然后从该列表或子shell中收集stderr。

文档

man bash解释了管道语法如下:

   Pipelines
       A  pipeline  is  a  sequence  of one or more commands separated by one of the control operators | or |&.  The format for a
       pipeline is:

              [time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]

   ...

   If  the  time reserved word precedes a pipeline, the elapsed as well as user and system time consumed by its execution are
   reported when the pipeline terminates.

答案 2 :(得分:1)

真的,你的grep不是个好主意。 Bash有一个很棒的time关键字,您可以根据需要设置其输出格式。

在你的情况下,我只是这样做:

TIMEFORMAT=$'real\t%3lR'
i=0
time while [ "$i" -lt 200000 ]; do i=$[$i+1]; done

请参阅Bash Variables section中的TIMEFORMAT规范。


现在,您的命令显示古董shell技术。在现代Bash中,您的while循环将写为:

while ((i<200000)); do ((++i)); done

关于time关键字,您还可以查看以下问题:Parsing the output of Bash's time builtin