苦苦挣扎解析(bash)时间命令

时间:2010-10-13 22:06:26

标签: bash time

我正在努力解析bash中time命令的输出 - 甚至在我调用它时阻止它打印输出。这是我的测试代码:

#!/bin/bash
TIME=`time ls -lh > /dev/null`
echo "Testing..."
echo $TIME

目前打印出来:

{blank-line}
real    0m0.064s
user    0m0.002s
sys     0m0.005s
Testing
{blank-line}

因此,分配给$TIME的值似乎是打印输出开始时的空白行。我需要得到sys系列的秒值 - 即“0.005”。我保证我将只有秒,所以我不需要任何“m”之前的任何东西 - 但是,如果它> = 10秒,秒部分可能是xx.xxx的形式。我目前不知道如何抑制'时间'输出,捕获所有输出而不是空白行,也不解析它以获得我需要的值。

非常感谢任何帮助......

5 个答案:

答案 0 :(得分:18)

如果您使用Bash内置time,则可以通过设置TIMEFORMAT变量来控制其输出:

TIMEFORMAT=%R

并且您不必进行任何解析,因为这会导致time仅输出秒数。

并使用此:

echo "Testing..."
TIME=$( { time ls -lh > /dev/null; } 2>&1 )
echo $TIME

或来自BashFAQ/032的其他技术之一。

答案 1 :(得分:7)

首先,您尝试捕获的数据正在写入标准错误。但在这种情况下捕获输出是相当棘手的。

time既是可执行文件(在/usr/bin中),也是bash和其他shell中的内置shell命令。在未指定time的情况下执行/usr/bin/time时,您正在bash中执行内置命令。这使得输出很难做到,因为bash并不像普通程序那样对待它;它是由bash编写的一个特殊的内置函数。

知道这一点,并查看time(1)的手册页,我可以看到您尝试从time捕获的数据输出到stderr。所以我的解决方法是直接执行/usr/bin/time,如下所示:

TIME=`/usr/bin/time ls -lh 2>&1 >/dev/null`

这会将标准错误流复制到标准输出,然后将标准输出通常重定向到/dev/null。但是,标准错误仍将标准化,因为它在重定向之前是重复的。颠倒这些顺序是行不通的。 (是的,这很令人困惑。)

不幸的是,/usr/bin/time的输出精确度稍低:

    0.00 real         0.00 user         0.00 sys

或者,您可以使用2个子shell,如下所示:

TIME=$((time ls -lh >/dev/null) 2>&1)

这将重写第一个shell中第二个子shell上写入标准错误的内容,允许您捕获输出。有关子shell的更多信息,请参阅http://www.tldp.org/LDP/abs/html/subshells.html

答案 2 :(得分:2)

虽然解决方案徘徊在相同的逻辑上,但我仍然无法找到以下列出的内容,因此解决方案的另一个版本:

TIME=$(time (ls -lh >/dev/null) 2>&1)

答案 3 :(得分:1)

time命令将时序信息输出到STDERR,您没有捕获或重定向。因此,在赋值时,该信息将打印到您的控制台,而$TIME变量获取命令的STDOUT - 您重定向到/dev/null,所以它是空白的。

也许您应该尝试捕获命令的STDERR?

答案 4 :(得分:0)

我想将此作为评论发布,但这会太长。我想提出另一种稍微不同的方法来获取数据。

您可以使用两个子shell将时间输出作为流使用/bin/sh而不是/usr/bin/time来获取执行的时间。我想你可以用time替换/usr/bin/time

$ ((time ./print_test.sh > deleteme) 2>&1) > deletemetime

$ cat deleteme
test

$ cat deletemetime
./print_test.sh > deleteme  0.00s user 0.00s system 86% cpu 0.003 total

$ ((time ./print_test.sh > deleteme) 2>&1) | sed 's/system/kernel/'
./print_test.sh > deleteme  0.00s user 0.00s kernel 86% cpu 0.003 total

另请注意,它产生输出的方式似乎有所不同。有时它采用这种格式,有时采用这种格式:

real    0m0.420s
user    0m0.385s
sys     0m0.040s

此时不确定是什么决定了这种或那种方式。

当然,您可以使用例如

TIMEFORMAT='%3R' 

修复格式。