‘grep’ 不能与 ‘time’ 一起使用吗?

‘grep’ 不能与 ‘time’ 一起使用吗?

为什么time ls | grep real输出这个

real    0m0.002s
user    0m0.000s
sys     0m0.002s

而不仅仅是

real    0m0.002s

如果我输入

echo -e 'real\t0m0.002s\nuser\t0m0.000s\nsys\t0m0.002s\n' | grep real

我得到了我期望的结果,即

real    0m0.002s

我发现这有效

(time ls)  2>&1 > /dev/null | grep real

这个命令起什么作用?

答案1

为什么不能time ls | grep real按预期工作。

timebash保留字,其行为与 不同/usr/bin/time

如果时间保留字位于管道之前,则会报告其执行所消耗的时间以及用户和系统时间当管道终止时

来源bash(1): GNU Bourne-Again SHell - Linux 手册页

此外,time输出到标准错误而不是标准输出。

使用以下命令:

(time ls) 2>&1 >/dev/null | grep real 

笔记:

  • (和将和命令)组合在一起(因此这些命令首先被评估)timels

  • 2>&1 >/dev/null首先将 stderr 重定向到 stdout (即管道),然后将 stdout 重定向到/dev/null

    因此 stderr 进入管道,而 stdout 则无处可去。


进一步阅读

答案2

是的,它可以工作,但是需要一点 I/O 重定向 :)

$ exec 3>&1 4>&2
{ time sleep 1 1>&3 2>&4; } 2>&1 |
    grep 'real'    
exec 3>&- 4>&-

输出 :

real    0m1,003s

bash 常见问题#32I/O 重定向教程


一个相当简单的方法:

$ TIMEFORMAT=%R
$ time sleep 1
1,003

答案3

这里有两个问题。

首先也是最重要的,“时间”将其输出发送到 stderr(标准错误)而不是 stdout,这样除非采取特殊措施,否则它不会被正常的重定向命令捕获。

其次,time 不是一个普通的程序,而是一个由 shell 直接解释的特殊内置命令(适用于 bash、csh、tcsh 等 shell)。因此,它以非标准方式工作,并对命令行的其余部分进行计时(除非您使用的是非常不常见的 shell)。

因此,为了获得想要的结果(使用 bash),您需要使用:

(time ls) 2>&1 | grep real

这将在子 shell 中运行“ls”并对其进行计时[(时间 ls)],将标准错误发送到标准输出[ 2>&1 ],然后将标准发送到“grep”[|grep]。

您使用的最后一部分“>?dev/null”会丢弃 ls 命令本身的正常输出,以防其中包含单词“real”。

答案4

看来time直接写入控制台而不是stdout,这意味着添加不会影响命令或管道的输出time

因此永远不会看到时间报告,因为整个管道都是计时的,grep所以无论如何它都是在完成后生成的。grep

相关内容