我想为一系列输入变量测量我的程序的运行时间(我正在使用 zsh):
for i in {1..3} ; do time sleep $i ; done
输出是
sleep $i 0,00s user 0,00s system 0% cpu 1,003 total
sleep $i 0,00s user 0,00s system 0% cpu 2,003 total
sleep $i 0,00s user 0,00s system 0% cpu 3,002 total
但我希望它是
sleep 1 0,00s user 0,00s system 0% cpu 1,003 total
sleep 2 0,00s user 0,00s system 0% cpu 2,003 total
sleep 3 0,00s user 0,00s system 0% cpu 3,002 total
如何time
打印实际命令,所有变量都替换为它们的值?
我已经尝试在子 shell 中运行程序,它没有按预期更改输出:
for i in {1..3} ; do time (sleep $i) ; done
由于我的程序为 stdout 和 stderr 生成自己的输出,因此我看不到一种方法可以简单地预先添加所有参数(还有一些不仅仅是i
),例如:
for i in {1..3} ; do echo -n "i=$i --> " ; time sleep $i ; done
您可以执行以下操作:
(
:q
在这种情况下,如果只包含数字,则不需要$i
,但在一般情况下,当想要将 的内容$i
作为文字参数传递给某个命令时)。您也可以随时用
%J
您想要的任何文本替换(扩展为工作名称¹)$TIMEFMT
:(请记住,如果
%
要包含在该文本中,则应将其转义为%%
)¹ 实际上,这并不是工作的名称。例如,您会发现
time sleep 1 | sleep 2
整个管道所在的位置time
为您提供了两条线,一条用于管道的每个部分。发生这种情况是因为
time
是一个可以作用于复合命令的关键字。(更准确地说,它作用于管道。)您可以编写类似并且 zsh 用于解析命令(包括计算
$i
)的时间是计时的一部分。一种解决方案是改用
time
外部命令。这作用于外部命令,因此 shell 扩展不是计时的一部分。使用 GNU 时间(默认情况下不打印命令):另一种解决方案是自己打印命令。请注意,下面的代码会在命令输出之前打印命令文本(如果有)。
另一种解决方案是激活命令跟踪。
另一种解决方案是将您想要的文本注入时间格式。
另一种解决方案是尽可能构建最简单的 shell 命令
eval
。由于这涉及eval
,因此如果命令可能包含 shell 特殊字符,请小心。