【命令】time — 执行命令并计时

【格式】time [-p] command [arguments...]

【说明】

执行命令行"command [arguments...]",命令行执行结束时在标准输出中打印执行该命令行的时间统计结果,其统计结果包含以下数据:

1)实际时间(real time): 从command命令行开始执行到运行终止的消逝时间;

2)用户CPU时间(user CPU time): 命令执行完成花费的用户CPU时间,即命令在用户态中执行时间总和;

3)系统CPU时间(system CPU time): 命令执行完成花费的系统CPU时间,即命令在核心态中执行时间总和。

其中,用户CPU时间和系统CPU时间之和为CPU时间,即命令占用CPU执行的时间总和。实际时间要大于CPU时间,因为Linux是多任务操作系统,往往在执行一条命令时,系统还要处理其它任务。

另一个需要注意的问题是即使每次执行相同命令,但所花费的时间也是不一样,其花费时间是与系统运行相关的。

例1:

           1. # time date
           2. Sun Mar 26 22:45:34 GMT-8 2006
           3.
           4. real    0m0.136s
           5. user    0m0.010s
           6. sys     0m0.070s
           7. #

在例1中,执行命令"time date"(见第1行)。系统先执行命令"date",第2行为命令"date"的执行结果。第3-6行为执行命令"date"的时间统计结果,其中第4行"real"为实际时间,第5行"user"为用户CPU时间,第6行"sys"为系统CPU时间。以上三种时间的显示格式均为MMmNN[.FFF]s。

在例1中,CPU时间 = 用户CPU时间 + 系统CPU时间 = 0m0.010s + 0m0.070s = 0m0.080s,实际时间大于CPU时间,说明在date命令运行的同时,还有其它任务在运行。

【参数说明】

-p 以POSIX缺省的时间格式打印时间统计结果,单位为秒。详细的输出格式见例2。

例2:

           1. # time -p date
           2. Wed Mar 27 00:33:11 GMT-8 2006
           3. real 0.11
           4. user 0.00
           5. sys 0.02
           6. #

在例2中,同样执行命令"time date"(见第1行)。系统先执行命令 "date",第2行为该命令的执行结果。第3-5行为执行命令"date"的时间统计结果。注意本例的时间格式与例1中的时间格式差别,使用-p 参数后的时间显示格式为NN.FF,其单位为秒。

【相关环境变量说明】

TIMEFORMAT 自定义输出的时间格式。

我们也可以通过环境变量TIMEFORMAT来自定义输出的时间格式[1]。格式中使用和标准C中的函数printf一致的转义符,以及使用以下的转义序列来指定输出的时间格式:

%[prec][l][RUS]

其中,选项prec为指定时间精度,即小数点后面的位数;选项l表示使用分秒(具体格式为:MMmNN[.FFF]s)的格式;最后一个字符表示时间的类型,其中R表示实际时间,U表示用户CPU时间,S表示系统CPU 时间,它们的单位均为秒。

time命令缺省输出的时间格式同 TIMEFORMAT=$'/nreal/t%3lR/nuser/t%3lU/nsys/t%3lS'。

使用-p参数的time命令输出的时间格式同 TIMEFORMAT=$'real %2R/nuser %2U/nsys %2S'。

例3:

           1. # export TIMEFORMAT=$'real %2R/nuser %2U/nsys %2S'
           2. # time date
           3. Wed Mar 27 00:52:03 GMT-8 2006
           4. real 0.04
           5. user 0.00
           6. sys 0.01
           7. #

比较例2和例3显示结果,很容易发现例3虽然没有使用参数-p,但其输出的结果和例2一模一样。

当然,我们也可以修改为任何自己喜欢的时间格式。

例4:

           1. # export TIMEFORMAT=$'/nHello, ThinkerABC!/nreal time :       %lR/nuser CUP time :   %lU/nsystem CPU time : %lS'
           2. # time date
           3. Wed Mar 27 01:09:26 GMT-8 2006
           4.
           5. Hello, ThinkerABC!
           6. real time :       0m0.016s
           7. user CUP time :   0m0.006s
           8. system CPU time : 0m0.008s
           9. #

例4的第4-8行正是我们自定义的输出格式。

从以上介绍了三种指定时间格式的方法,即缺省的时间格式、使用参数-p的POSIX缺省的时间格式和设定环境变量TIMEFORMAT自定义的时间格式,Linux系统使用的先后顺序如下:

1.参数-p的POSIX缺省时间格式;

2.环境变量TIMEFORMAT自定义的时间格式;

3.缺省的时间格式。

【退出状态说明】

如果能执行command命令,则返回该命令的退出状态,否则返回如下的退出状态值:

127 命令未找到

126 命令找到,但不能执行

1-125 其它错误

摘自:http://blog.csdn.net/thinkerabc/article/details/647272


重定向Bash命令——time


假定我们只关心用户态时间,那么可以直接使用time command | grep user来获取。但是再使用这个命令后,我们却无法像往常一样grep到我们想要的信息。于是man time查看帮助后,我们得知,原来time会默认将输出写到stderr中,那么很简单,我们可以time command 2>&1 | grep user,这样将stderr重定向到stdout,再进行grep就可以了。可以结果还是出乎我们的预料,依然无法grep。google一番之后才知道,这里的time其实是一个shell的keyword,它的处理方式不同于普通的shell command。


NOTE: 可以通过 type 命令来查看一个command的类型,比如:

   $ type [

   [ is a shell builtin

   $ type time

   [ is a shell keyword


正文:


重定向Shell关键字time


在一个Shell脚本中,我想要获得一个命令的执行时间,并把结果重定向到一个文件中。首先我尝试如下命令:


$ time command > time.txt


不起作用。于是我发现time是输出到stderr上的。我将命令改为:


$ time command 2> time.txt


还是没用。time还是把结果打印到了console上。


显然time是一个bash的保留字。它不像大多数内建的bash命令一样,但却是命令行语法(command line syntax)的一部分,就像 if 和 while。


Bash 3.1.0的手册中提到了关于pipeline和保留字time的信息:

    Pipelines
      A pipeline is a sequence of one or more commands separated by the char-
      acter |.  The format for a pipeline is:

             [time [-p]] [ ! ] command [ | command2 ... ]

      The standard output of command is connected via a pipe to the standard
      input  of  command2.   This connection is performed before any redirec-
      tions specified by the command (see REDIRECTION below).

      The return status of a pipeline is the exit status of the last command,
      unless  the  pipefail  option  is enabled.  If pipefail is enabled, the
      pipeline's return status is the value of the last  (rightmost) command
      to  exit  with a non-zero status, or zero if all commands exit success-
      fully.  If the reserved word !  precedes a pipeline, the exit status of
      that  pipeline  is the logical negation of the exit status as described
      above.  The shell waits for all commands in the pipeline  to  terminate
      before returning a value.

      If  the  time reserved word precedes a pipeline, the elapsed as well as
      user and system time consumed by its execution are  reported  when  the
      pipeline  terminates.   The -p option changes the output format to that
      specified by POSIX.  The TIMEFORMAT variable may be  set  to  a  format
      string  that  specifies how the timing information should be displayed;
      see the description of TIMEFORMAT under Shell Variables below.

      Each command in a pipeline is executed as a separate process (i.e.,  in
      a subshell).


NOTE: 这里我们看到,一个包含管道的命令,默认的返回值将是最后一个子命令的返回值。


内建的help命令提到:


$ 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.
times: times
   Print the accumulated user and system times for processes run from
   the shell.


这就暗示说,使用bash的关键字time,会使得命令运行在一个子shell中,即使没有使用管道也是一样。

我还没有确认过这点,但是这确是为我们获得命令的执行时间提供的一些线索。


从语法描述中我们可以清楚的看到,time的输出不会被追加到命令的stderr中,而是由shell自身输出的。

关键字time设置了一个标记,知道pipeline命令执行完,timing信息才被打印到stderr中。time关键字要整个command和管道,还有相关的重定向都要来得高级。这就是为什么简单的重定向对于time而言不起作用。这是Bash语法定义的。command之后的重定向对于time而言,是command的一部分。


重定向time的输出可以通过将整个time命令放入一个子shell中来实现:

$ (time command) 2> time.txt


启动一个子shell不是必须的。我们同样可以使用下面的代码:

$ { time ls; } 2> time.txt


这可能比执行外部命令/usr/bin/time效率更高。当然time命令(外部命令)可能有你所需的更多的功能。

或许你想要依赖于bash time(关键字),因为你不知道系统安装的time(外部命令)工具是否有你所需的功能。


在重定向和管道行为这两方面来看,使用上述命令同执行外部的time命令是等价的。


可以通过将stdout和stderr重定向到/dev/null来抑制命令本身的输出。


NOTE: 作者这里也提到,可以使用外部命令来完成关键字time提供的功能。

摘自:http://blog.csdn.net/seizef/article/category/639191