Bash 时间命令输出与环境变量赋值不同

Bash 时间命令输出与环境变量赋值不同

通常该time命令输出三行:

> time sleep 2
real    0m2.003s
user    0m0.000s
sys     0m0.006s

但是,当加上变量赋值后,输出将变成一行:

> VAR="" time sleep 2
0.00user 0.00system 0:02.00elapsed 0%CPU (0avgtext+0avgdata 2060maxresident)k
0inputs+0outputs (0major+86minor)pagefaults 0swaps

为什么会发生这种情况?有没有办法在输出三行的同时保留变量赋值?

答案1

为什么会发生这种情况?

在 Bash 中time有一个保留字 (关键词) 不仅可以放在简单命令之前进行测量,还可以测量管道。因此,它必须是第一个词。此语法仅通知 Bash 您想要测量时间;管道的其余部分仍由 Bash 处理,就像time不存在一样。

如果time不是第一个单词,但仍然可以解释为命令,则将其解释为常规外部命令(甚至不是内置命令),查找$PATH并执行;例如它可以是/usr/bin/time。此工具处理其参数并从中构建实际命令。

这两个实用程序产生不同格式的输出。


有没有办法在将输出分为三行的同时保留变量赋值?

是的。您可以将其用作time第一个单词,这样它就会被解释为关键字:

time VAR="" sleep 2

注意,两种实现都支持-p将输出格式更改为由 POSIX 指定(事实上-p​​ POSIX 要求它本身的支持)。这意味着以下两个命令将产生相同格式的输出:

time -p VAR="" sleep 2
VAR="" time -p sleep 2

然而,从本质上讲,它们是非常不同的。

答案2

时间将其输出发送到 STDERR 而不是 STDOUT。

有几个选项,但我不清楚您计划如何使用捕获的数据,所以我将把它分成三行。

$ narf="$( ( time sleep 2 ) 2>&1 )" ; echo "${narf}" ; unset narf  

real    0m2.002s
user    0m0.001s
sys 0m0.001s

$ narf="$( ( time sleep 5 ) 2>&1 )" ; echo "${narf}" ; unset narf  

real    0m5.002s
user    0m0.001s
sys 0m0.001s

$ narf="$( ( time -p sleep 5 ) 2>&1 )" ; echo "${narf}" ; unset narf  
real 5.00
user 0.00
sys 0.00

前两个选项不使用 -p 格式选项(该选项设计用于符合 POSIX 标准)。第三个选项则使用 -p 格式选项。

如您所见,输出略有不同。如果您愿意,可以问我问题。(您可以删除 unset 命令,因为我使用它来执行多个测试。)

相关内容