如何通过管道“时间”控制其他进程?

时间:2015-05-06 12:40:02

标签: time pipe sh

在一般情况下,我们有一个像P | Q | R这样的命令,它具有shell的以下语义:

  • 创建流程PQR
  • P的输出绑定到Q
  • 的输入
  • Q的输出绑定到R
  • 的输入
  • P的输出绑定到shell输入
  • R的输出绑定到shell输出
  • 运行PQR

这是明确的。但是让我们观察以下内容:

$ time echo lol | cat | wc -l
echo lol  0.00s user 0.00s system 10% cpu 0.005 total
cat  0.00s user 0.00s system 81% cpu 0.001 total
wc -l  0.00s user 0.00s system 83% cpu 0.001 total

这里我们有时间工作,因为它完全了解管道中的所有内容,而从语法的角度来看,我希望它只知道echo lol,它会被启动 - 我猜 - 作为子进程。

如果time是内置的shell,这很容易做到,但事实并非如此,至少在我的GNU / Linux操作系统上:which time给了我/usr/bin/timebash联机帮助页未提及内置time

我想不出任何其他具有相似特征的程序。 time程序有一个特殊的例外,还是一个非常模糊的系统调用允许这种交互?

1 个答案:

答案 0 :(得分:3)

您为time echo lol | cat | wc -l显示的输出确实需要time作为内置shell(实际上比内置的shell更罕见:关键字,如if和{{ 1}}。)

您的调查存在一些缺陷。首先,您不清楚自己使用的是哪种外壳。示例中for输出的具体格式由zsh生成,zsh具有time关键字。它记录在zshmisc(1)中。

bash也有一个time关键字,但它不会为管道中的每个命令生成单独的输出。在bash手册页中很难找到,因为他们忽略了将其列在其他关键字中,但它在标题" SHELL GRAMMAR",subheading" Pipelines" :

  

如果时间保留字在管道之前,则在管道终止时报告其执行所消耗的经过时间以及用户和系统时间。 -p选项将输出格式更改为POSIX指定的格式。 TIMEFORMAT变量可以设置为格式字符串,指定如何显示定时信息;请参阅下面的Shell变量下的TIMEFORMAT说明。

您的其他错误是在zsh中运行示例time命令之后使用which,这显然是在bash中执行的。在zsh中有一个内置time可以告诉你其他内置函数。在bash中没有。所以你运行了一个外部命令which,它无法知道你的shell内置了什么;它只能告诉您which中找到的time

有一些与$PATH相关的zsh内置版本;我喜欢which命令,该命令列出找到命令的所有所有,而不是当前搜索顺序中第一个的。在bash中,您应该使用where命令来确定某些内容是否是内置的。

type

注意:这个答案基于bash 4.1.17和zsh 5.0.6,这是我可以轻松测试的版本。如果有一些版本的bash复制了zsh bash$ type time time is a shell keyword zsh% where time time: shell reserved word /usr/bin/time 格式,那么答案会更加可信,但据我所知,它还没有存在。