重定向Bash命令——time

前言:

      由于需要获得一个程序的运行时间,我们可以在Shell里简单地调用time command的形式来获取一个程序运行的real, user, system等时间信息,但是默认输出的形式类似:

 

     real  0m0.077s

   user  0m0.077s

   sys   0m0.077s

 

假定我们只关心用户态时间,那么可以直接使用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://www.cs.tut.fi/~jarvi/tips/bash.html

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值