我有以下命令行:
time `while [ $i -lt 200000 ]; do i=$[$i+1]; done` | grep "real"
根据我所知的bash,这应该首先给我while循环的运行时间并将其用作grep
命令的输入,然后grep
命令应该只打印出真实的time
命令给出的时间,而是打印time
命令的完整输出
那么为什么它没有像我期望的那样工作。还有更好的方法吗?
答案 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
:
$ 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。