如何在Shell脚本中以秒为单位测量持续时间?


74

我希望找出一个Linux Shell脚本需要花费多长时间。我怎样才能做到这一点?

Answers:


111

正如其他人所建议的那样,使用time命令是一个好主意。

另一个选择是使用内置的魔术变量$ SECONDS,该变量包含自脚本开始执行以来的秒数。你可以说:

START_TIME=$SECONDS
dosomething
ELAPSED_TIME=$(($SECONDS - $START_TIME))

我认为这是特定于bash的,但是由于您使用的是Linux,因此我假设您正在使用bash。


4
我要在此添加的唯一警告是,对于您自己的变量使用全大写字母的名称是错误的形式,因为这意味着您可能会错误地覆盖shell-builtin变量(f / e,如果有人将赋给SECONDS,则它不再具有特殊的含义)。请参阅POSIX规范@ pubs.opengroup.org / onlinepubs / 9699919799 / basedefs/…,保留小写字母供应用程序使用,请牢记shell和环境变量共享一个名称空间-保留包含小写字母的环境变量名称的名称空间适用于应用程序。
查尔斯·达菲

40

使用time命令。time ls /bin


1
time不适合的时正在执行复杂的指令序列
Shiplu Mokaddim

4
@ shiplu.mokadd.im不?如何:time (ls / ; sleep 2; ls /bin)
基思(Keith)

如果使用\ ()它将变得更加复杂。
Shiplu Mokaddim 2013年

3
@ shiplu.mokadd.im-为什么不合适?说明。对我来说似乎不错/准确,并且已经使用了很多年……
bshea

1
@Keith这有一些问题,例如/usr/bin/time -f '%C => %E' (ls / ; sleep 2; ls /bin)抛出bash: syntax error near unexpected token '('
Shiplu Mokaddim

35

请尝试以下示例:

START_TIME=$SECONDS
# do something
sleep 65

ELAPSED_TIME=$(($SECONDS - $START_TIME))

echo "$(($ELAPSED_TIME/60)) min $(($ELAPSED_TIME%60)) sec"    
#> 1 min 5 sec

9

许多答案都提到了$SECONDS这个变量,但实际上它比他们意识到的还要好

分配给该变量会将计数重置为分配的值,并且扩展后的值将成为分配的值加上分配以来的秒数。

这意味着您可以直接在脚本结尾直接查询此变量以显示经过的时间:

#!/usr/bin/env bash

# Do stuff...

echo "Script finished in $SECONDS seconds."

您还可以为较小的部分设置时间,如下所示:

#!/usr/bin/env bash

# Do stuff

SECONDS=0

# Do timed stuff...

echo "Timed stuff finished in $SECONDS seconds."

5

这是查找经过的时间(以毫秒为单位)的脚本。用您要执行的代码替换sleep 60行。

a=0
while [ $a -lt 10 ]
do
    START_TIME=`echo $(($(date +%s%N)/1000000))`
    sleep 3
    END_TIME=`echo $(($(date +%s%N)/1000000))`
    ELAPSED_TIME=$(($END_TIME - $START_TIME))
    echo $ELAPSED_TIME
    if [ $a -eq 10 ]
    then
        break
    fi
    a=`expr $a + 1`
done

3

只是为了帮助像我这样的人遇到错误:

 arithmetic expression: expecting primary: "-"

检查应以以下内容开头的shellscript:

#!/bin/bash

干杯!


1

GNU time

我对GNUtime命令也很感兴趣:https : //www.gnu.org/software/time/time内置的Bash相比,它提供了一些重要的选项。

用法示例:

env time --format '%e' --output time.log sleep 1

输出:

1.00

说明:

  • env:查找/usr/bin/time而不是内置的Bash

  • --format '%e':以秒为单位的打印时间,请参见man time

    基准测试时通常是我想要的:一个数字,而不是分钟+秒。

我经常使用的一个重要模式是:

bench-cmd() (
  logfile=time.log
  echo "cmd $@" >> "$logfile"
  printf 'time ' >> "$logfile"
  bench_cmd="env time --append --format '%e' --output '$logfile' $@"
  eval "$bench_cmd"
  echo >> "$logfile"
)

rm -f time.log
bench-cmd sleep 1
bench-cmd sleep 2
bench-cmd sleep 3
cat time.log

GitHub上游

输出:

cmd sleep 1
time 1.00

cmd sleep 2
time 2.00

cmd sleep 3
time 3.00

说明:

  • --output:将时间输出到文件。

    默认情况下,输出到达stderr,因此此选项对于将时序与命令的stderr分开很重要。

  • --append:追加到文件而不是覆盖。

    这使我可以将整个基准测试输出集中在一个文件中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.