有没有办法find最后执行的命令在shell中的运行时间?

有像time这样的命令,可以显示shell上最后或过去执行的命令的运行时间细节吗?

我不知道bash是如何实现的,但是在zsh中,你可以定义preexecprecmd函数,以便将当前时间保存到变量$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. 没有现成的方法来计算已经运行的命令
  2. 有一些方法可以推断出命令运行时间的持续时间。
  3. 显示了一个概念证明(从假设是不能完成的,并以假设是错误的结论开始)。
  4. 你可以事先放置一些黑客来记录你运行的每一个命令的运行时间
  5. 结论

根据上面的概述,其部分标注的答案是:

第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命令使用给定的参数运行指定的程序命令。 当命令完成时,时间将消息写入标准错误,给出有关此程序运行的计时统计信息。