将UNIX中的时间命令输出重定向到bash中的变量中?


13

我只想捕获时间命令的输出,即:

X=$(time ls)

要么

$(time ls) | grep real

时间函数将其吐到控制台。我该怎么做呢?

Answers:


12

X =`(time ls)2>&1 | grep real`


您不需要仅用于以下目的的子shell time:在这方面,丹尼斯·威廉姆森的答案更好。
musiphil

11

参见BashFAQ / 032

$ # captures output of command and time
$ time=$( TIMEFORMAT="%R"; { time ls; } 2>&1 )    # note the curly braces

$ # captures the time only, passes stdout through
$ exec 3>&1 4>&2
$ time=$(TIMEFORMAT="%R"; { time ls 1>&3 2>&4; } 2>&1)
bar baz
$ exec 3>&- 4>&-

时间将看起来像“ 0.000”,使用TIMEFORMAT="%R"它将是“真实”时间。


您能解释一下这是如何工作的吗?多年来,我一直在使用类似这种货运崇拜风格的代码段。什么是流3和4?和“-”?
Sirex's

1
@Sirex:流3和4是exec命令在我的答案中使用可用文件描述符创建的流。可以使用任何可用的文件描述符。流3和4分别是1(stdout)和2(stderr)的副本。这允许的输出ls正常传递给3和4 ,stdoutstderr通过3和4,而的输出time(通常传递给stderr)被重定向到原始stdout(1),然后使用命令替换捕获到变量中。如您在我的示例中所见,文件名barbaz被输出到终端。...
暂停,直到另行通知。

1
...完成后,使用尾随将多余的流关闭-
暂停,直到另行通知。

4

时间将其输出写入STDERR而不是STDOUT。更糟糕的是,默认情况下,“ time”是shell内置命令,因此,如果您尝试“ time ls 2>&1”,则“ 2>&1”仅适用于“ ls”。

解决方案可能是这样的:

/usr/bin/time -f 'real %e' -o OUTPUT_FILE ls > /dev/null 2>&1<br>
REALTIME=$(cat OUTPUT_FILE | cut -f 2 -d ' ')

有很多花哨的方法可以做到这一点,但这是清晰/简单的方法。


我有兴趣在没有-o的情况下执行此操作。您能张贴一种您想过的奇特方法:)吗?
David Doria 2014年

0

@Dennis Williamson的答案很好,但是它不能帮助您将命令的输出存储在一个变量中,而将命令的输出存储time在另一个变量中。使用文件描述符实际上是不可能的。

如果要记录程序运行的时间,可以通过从结束时间中减去开始时间来完成。这是一个简单的示例,显示程序运行了多少毫秒:

START_TIME=$(date +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(date +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"

这个time命令的准确性不高,但是对于大多数bash脚本来说,它应该可以正常工作。

不幸的是,Mac的date命令不支持该%N格式,但是您可以安装coreutilsbrew install coreutils)并使用gdate

START_TIME=$(gdate +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(gdate +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"
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.