哪些代码可以在 bash 和 zsh 中使用“time”关键字(使用内置函数)工作?

哪些代码可以在 bash 和 zsh 中使用“time”关键字(使用内置函数)工作?

在 bash 中,通常time cmd对多种类型的(s) 执行以下操作:cmd

$ time true
real    0m0.000s
user    0m0.000s
sys     0m0.000s

输出格式可以更改(甚至可以更改为带有 time -p 的 posix 格式):

$ TIMEFORMAT='real %R'; time true
real 0.000

但是 zsh 不报告简单命令的时间(也可以尝试time echo):

% time true

将命令转换为管道会报告其他内容:

$ zsh -c 'time echo yes | cat'
yes
echo yes  0.00s user 0.00s system 26% cpu 0.001 total
cat  0.00s user 0.00s system 85% cpu 0.002 total

可以通过子 shell 强制 shell 给出时间输出(…)

$ zsh -c 'time ( true )'
( true; )  0.00s user 0.00s system 26% cpu 0.005 total

但这不适用于{…},也不适用于以下内置函数for

$ zsh -c 'time { for i in $(seq 100); do ls; done >/dev/null; }'

zsh 的时间如何能够在没有子 shell 的情况下接受简单的命令。

或者,一个更简单的问题:

有没有办法编写在 ksh、bash、zsh 中使用 time 关键字运行的代码?

答案1

time不对命令计时。 来自单一 Unix 规范的理由:

期限公用事业被使用,而不是命令,强调 shell 复合命令、管道、特殊内置命令等不能直接使用的事实。

不锈钢time还指出,结果特别的内置命令未定义,其结果用于除简单的命令(即在管道或命令分组上)未指定。

这是因为time不是不需要是特殊的 shell 语法,也不需要是内置命令。是否在第一次标准化时变化很大,现在也变化很大。

  • 在 Almquist 和 (Heirloom) Bourne shell 中,time既不是保留字也不是内置命令。它是一个外部命令,因此不能应用于除简单的命令timeBSD上的外部命令使用wait4()库函数从内核返回的进程使用信息,如果要对shell内置命令和管道进行计时,则要求被计时的程序是shell。因此,诸如time bindkey找不到要执行的实用程序之类的事情以及诸如time echo对操作进行计时之类的事情外部的 echo命令而不是 shell 内置命令。
  • 在 C shell 中,time是一个内置命令,不能应用于除简单的命令time通过查看库函数的结果来工作wait4(),这需要一个子进程来等待。所以C shell的time 总是分叉一个子进程,即使对于其他内置命令也是如此。您会发现诸如此类的事情time bindkey -v一无所获,因为它们是在子进程中运行的结果time
  • 在 Korn 和 Bourne Again shell 中,time是 shell 语法中的保留字,可应用于管道。这些 shell 不使用wait4()库函数返回的子进程使用信息,而是通过将命令调用与对 的调用括起来getrusage()并进行减法来计算时间。
  • 在 Z shell 中,time是 shell 语法中的保留字,可应用于管道。 Z shell 确实使用库函数从内核返回的进程使用信息wait4(),但不会强制分叉内置命令。所以它没有报告任何内容当没有子进程被分叉时(就像内置命令的情况一样true);但相反,喜欢time set -o vi实际取得一些成就。

正如其基本原理所述,单一 Unix 规范措辞宽松,以允许所有不同的行为。它表明计时 shell 内置命令是一个问题。

答案2

虽然大多数 shell 支持对外部和内置命令进行计时,但 zsh 不支持对内置命令进行计时。

如果您需要获得时间结果,您可以致电

time /bin/true

或者向 zsh 人员发送错误报告。

随着新信息的出现,事情看起来有所不同。

time计时复杂命令仅在shell 中为保留字的情况下才有效。

所以你有两个限制因素

  • shell 需要能够对内置命令进行计时

  • shell 需要实现time为增强 shell 语法的保留字

这将潜在的 shell 候选列表减少为:

bosh bash mksh ksh

对于内置命令,shell 需要知道如何测量自己的计时。

对于复杂的命令,shell需要time在解释器内部实现。

相关内容