在shell中获取程序执行时间

ʞɔı*_*ɔıu 390 linux bash shell

我想在几个不同的条件下在linux shell中执行一些东西,并能够输出每次执行的执行时间.

我知道我可以编写一个可以执行此操作的perl或python脚本,但有没有办法在shell中执行此操作?(恰好是bash)

Rob*_*ble 512

使用内置time关键字:

$ help time

time: time [-p] PIPELINE
    Execute PIPELINE and print a summary of the real time, user CPU time,
    and system CPU time spent executing PIPELINE when it terminates.
    The return status is the return status of PIPELINE.  The `-p' option
    prints the timing summary in a slightly different format.  This uses
    the value of the TIMEFORMAT variable as the output format.

例:

$ time sleep 2
Run Code Online (Sandbox Code Playgroud)
real    0m2.009s
user    0m0.000s
sys     0m0.004s

  • @natli:虽然`time`可以按原样计算整个管道(由于是Bash _keyword_),但你需要使用_group command_(`{...; ...;}`)来计算_multiple_命令:`time -p {i = x; 读线; 做x = x; 完成</path/to/file.txt; }` (8认同)
  • @Znik,试试/ usr/bin/time (5认同)
  • 它如何用在像 `time -pi=x; 这样的命令上?读取行时;x=x;完成&lt;/path/to/file.txt`?它立即返回 0.00 除非我在 while 循环之前没有放置任何内容.. 给出了什么? (2认同)
  • 要查看系统上安装的所有时间版本,可以使用`type -a time`。 (2认同)

gre*_*awk 117

time使用时间(1),您可以获得比内置的bash (Robert Gamble提到的)更详细的信息.通常这是/usr/bin/time.

编者注:为了确保您调用外部实用程序 time而不是shell的time 关键字,请将其调用为/usr/bin/time.
time是一个POSIX强制实用程序,但它需要支持的唯一选项是-p.
特定平台实现特定的非标准扩展:-vGNUtime实用程序一起工作,如下所示(问题标记为); BSD/macOS实现用于-l产生类似的输出 - 见man 1 time.

详细输出示例:


$ /usr/bin/time -v sleep 1
       Command being timed: "sleep 1"
       User time (seconds): 0.00
       System time (seconds): 0.00
       Percent of CPU this job got: 1%
       Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05
       Average shared text size (kbytes): 0
       Average unshared data size (kbytes): 0
       Average stack size (kbytes): 0
       Average total size (kbytes): 0
       Maximum resident set size (kbytes): 0
       Average resident set size (kbytes): 0
       Major (requiring I/O) page faults: 0
       Minor (reclaiming a frame) page faults: 210
       Voluntary context switches: 2
       Involuntary context switches: 1
       Swaps: 0
       File system inputs: 0
       File system outputs: 0
       Socket messages sent: 0
       Socket messages received: 0
       Signals delivered: 0
       Page size (bytes): 4096
       Exit status: 0

  • 令人惊讶的是,它是从一个名为"时间"的包中安装的. (24认同)
  • @Nick:"sudo apt-get install time". (4认同)
  • 您不会偶然知道它将来自哪个debian软件包?似乎没有默认安装 (2认同)
  • / usr/bin/time的输出看起来像"0.00user 0.00system 0:02.00elapsed 0%CPU(0avgtext + 0avgdata 0maxresident)k 0inputs + 0outputs(0major + 172minor)pagefaults 0swaps" (2认同)

小智 79

#!/bin/bash
START=$(date +%s)
# do something
# start your script work here
ls -R /etc > /tmp/x
rm -f /tmp/x
# your logic ends here
END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"
Run Code Online (Sandbox Code Playgroud)

  • 有更简单的方法.Bash自动计算特殊变量$ SECONDS,然后根据外部日期命令重新计算是不需要的.$ SECONDS变量保持bash脚本启动时运行的秒数.此变量具有一些特殊属性.见手册页:D (14认同)

Adr*_*nde 43

对于逐行delta测量,请尝试gnomon.

命令行实用程序,有点像moreutils的ts,用于将时间戳信息添加到另一个命令的标准输出.对于长期运行的过程非常有用,在这些过程中,您需要记录长时间运行的历史记录.

您还可以使用--high和/或--medium选项指定以秒为单位的长度阈值,gnomon将以红色或黄色突出显示时间戳.你也可以做其他一些事情.

例

  • 一个很好的提示,但要明确一点:这对于逐行计时很有用,但是采用这种细粒度计时的开销会显着增加总体计时。 (3认同)
  • 很棒的工具..感谢分享 (2认同)
  • 大gif!感谢您的努力 (2认同)

Ben*_*fez 18

如果你想要更精确,使用%Ndate(和使用bc的差异,因为$(())只处理整数).

这是怎么做的:

start=$(date +%s.%N)
# do some stuff here
dur=$(echo "$(date +%s.%N) - $start" | bc)

printf "Execution time: %.6f seconds" $dur
Run Code Online (Sandbox Code Playgroud)

例:

start=$(date +%s.%N); \
  sleep 0.1s; \
  dur=$(echo "$(date +%s.%N) - $start" | bc); \
  printf "Execution time: %.6f seconds\n" $dur
Run Code Online (Sandbox Code Playgroud)

结果:

Execution time: 0.104623 seconds
Run Code Online (Sandbox Code Playgroud)


Nor*_*sey 15

如果您打算稍后使用计算时间,请了解如何使用-f选项/usr/bin/time输出可节省时间的代码.这里是我最近使用的一些代码,用于获取和整理整个学生课程的执行时间:

fmt="run { date = '$(date)', user = '$who', test = '$test', host = '$(hostname)', times = { user = %U, system = %S, elapsed = %e } }"
/usr/bin/time -f "$fmt" -o $timefile command args...
Run Code Online (Sandbox Code Playgroud)

我后来连接了所有$timefile文件并将输出传输到Lua解释器.您可以使用Python或bash或任何您喜欢的语法执行相同的操作.我喜欢这种技巧.


gle*_*man 12

如果你只需要精确到秒,你可以使用builtin $SECONDS变量,它计算shell运行的秒数.

while true; do
    start=$SECONDS
    some_long_running_command
    duration=$(( SECONDS - start ))
    echo "This run took $duration seconds"
    if some_condition; then break; fi
done
Run Code Online (Sandbox Code Playgroud)

  • 或者只是`... SECONDS=0; 一些_长_运行_命令;echo“本次运行花费了 $SECONDS 秒”...`,参见 男人狂欢 (2认同)

Edu*_*omo 9

你可以使用time子shell ():

time (
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
)
Run Code Online (Sandbox Code Playgroud)

或者在同一个shell中{}:

time {
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
}
Run Code Online (Sandbox Code Playgroud)

  • @StasBekman不是真的,首先使用`(`&`)`(new context,_subshel​​l_),以及其他````````(相同的shell,相同的上下文) (3认同)