有像time
这样的命令,可以显示shell上最后或过去执行的命令的运行时间细节吗?
我不知道bash是如何实现的,但是在zsh中,你可以定义preexec
和precmd
函数,以便将当前时间保存到变量$STARTTIME
(preexec)和$ENDTIME
(precmd)中,以便能够找到近似值运行时间。 或者你可以定义一个accept-line
函数,这样它会在每个命令之前加上time
。
更新 :这是代码,将存储在$_elapsed
数组中的经过时间:
preexec () { (( $#_elapsed > 1000 )) && set -A _elapsed $_elapsed[-1000,-1] typeset -ig _start=SECONDS } precmd() { set -A _elapsed $_elapsed $(( SECONDS-_start )) }
那么如果你运行sleep 10s
:
% set -A _elapsed # Clear the times % sleep 10s % sleep 2s ; echo $_elapsed[-1] 10 % echo $_elapsed 0 10 0
不需要四个变量。 没有名称或额外延误的问题。 请注意, $_elapsed
数组可能会变得非常大,所以你需要删除第一个项目(这是用下面的一段代码完成的: (( $#_elapsed > 1000 )) && set -A _elapsed $_elapsed[-1000,-1]
)。
UPDATE2 :找到脚本来支持bash中的zsh-style precmd和preexec。 也许你会需要删除typeset -ig
(我只是强制$_start
为整数),并用var=( ... )
替换set -A var ...
才能正常工作。 我不知道如何切片数组,并得到他们的长度在bash中。
脚本: http : //www.twistedmatrix.com/users/glyph/preexec.bash.txt
UPDATE3 :发现一个问题:如果用空行命中return preexec不运行,而precmd则运行,所以您将在$_elapsed
数组中获得无意义的值。 为了解决这个问题,用下面的代码替换precmd
函数:
precmd () { (( _start >= 0 )) && set -A _elapsed $_elapsed $(( SECONDS-_start )) _start=-1 }
编辑3:
这个答案的结构:
根据上面的概述,其部分标注的答案是:
第1部分 – 简短的答案是“否”
原版的
不,谢谢。 你必须使用time
。
第2部分 – 也许你可以推断出一个结果
在某些情况下,如果一个程序将输出文件或信息写入日志文件中,您可能可以推断出运行时间,但这将是程序特定的,只是一个猜测。 如果您在Bash中设置了HISTTIMEFORMAT,则可以查看历史记录文件中的条目,以了解程序何时启动。 但是结束时间并没有被记录下来,所以如果在你感兴趣的完成之后立即开始另一个程序,你只能推断一个持续时间。
第三部分 – 假设是伪造的
假设 :空闲时间将被计算在经过的时间
编辑:
这里举一个例子来说明我的观点。 这是基于ZyX的建议,但使用其他方法将会类似。
在zsh
:
% precmd() { prevstart=start; start=$SECONDS; } % preexec() { prevend=$end; end=$SECONDS; } % echo "T: $SECONDS ps: $prevstart pe: $prevend s: $start e: $end" T: 1491 ps: 1456 pe: 1458 s: 1459 e: 1491
现在我们等待…让我们说15秒,然后:
% echo "T: $SECONDS"; sleep 10 T: 1506
现在我们等待…让我们说20秒,然后:
% echo "T: $SECONDS ps: $prevstart pe: $prevend s: $start e: $end" T: 1536 ps: 1492 pe: 1506 s: 1516 e: 1536
正如你所看到的,我错了 。 开始时间(1516)减去前一结束时间(1506) 是命令( sleep 10
)的持续时间。 这也表明,我在函数中使用的变量需要更好的名称。
假设伪造 – 可以在不包括空闲时间的情况下获得正确的经过时间
第4部分 – 记录每个命令的运行时间
编辑2:
这里是ZyX的答案(他们需要脚本链接到那里)功能的Bash等价物:
preexec () { (( ${#_elapsed[@]} > 1000 )) && _elapsed=(${_elapsed[@]: -1000}) _start=$SECONDS } precmd () { (( _start >= 0 )) && _elapsed+=($(( SECONDS-_start ))) _start=-1 }
在安装preexec.bash
(从链接的脚本)并创建上面的两个函数后,示例运行如下所示:
$ _elapsed=() # Clear the times $ sleep 10s $ sleep 2s ; echo ${_elapsed[@]: -1} 10 $ echo ${_elapsed[@]} 0 10 2
第五部分 – 结论
使用time
。
我认为你所运行的命令需要很长时间,而且一开始并没有意识到你想花时间来完成。 在zsh中,如果将环境变量REPORTTIME设置为一个数字,则任何花费比该秒数更长的命令都会花费打印的时间,就像您使用前面的time命令运行一样。 您可以在.zshrc中设置它,以便长时间运行的命令将始终打印它们的时间。 请注意,睡眠时间(而不是用户/系统时间)不计入触发定时器,但仍然被跟踪。
由于其他人回答了这些问题,这个世界可能会有一点点变化。
zsh
有一些内置的功能来计算命令执行的时间。
如果您启用inc_append_history_time选项
setopt inc_append_history_time
然后,运行每个命令所需的时间将保存在您的历史记录中,然后可以通过history -D
查看history -D
。
我认为你只能得到使用命令'time'运行的命令的时间统计。
从手册页:
时间[选项]命令[参数…]
说明time命令使用给定的参数运行指定的程序命令。 当命令完成时,时间将消息写入标准错误,给出有关此程序运行的计时统计信息。