在一般情况下,我们有一个像P | Q | R
这样的命令,它具有shell的以下语义:
P
,Q
,R
P
的输出绑定到Q
Q
的输出绑定到R
P
的输出绑定到shell输入R
的输出绑定到shell输出P
,Q
,R
这是明确的。但是让我们观察以下内容:
$ 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/time
, bash
联机帮助页未提及内置time
。
我想不出任何其他具有相似特征的程序。 time
程序有一个特殊的例外,还是一个非常模糊的系统调用允许这种交互?
答案 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
格式,那么答案会更加可信,但据我所知,它还没有存在。