Contents

重定向time命令的输出

1. 概述

Linux 中的time 命令测量可执行文件的执行时间。可执行文件可以是命令、程序或脚本。 time命令将其输出打印到标准错误,默认情况下是终端窗口。我们可能需要将time命令的输出重定向到一个文件并在以后使用它。

在本教程中,我们将讨论如何将time命令的输出重定向到文件。

2. 重定向问题

让我们尝试使用time命令来测量命令的持续时间:

$ time sleep 2
real    0m2.003s
user    0m0.001s
sys     0m0.002s

当我们运行time sleep 2命令时,实际运行sleep 2命令所花费的时间为 2.003 秒。time命令的输出还包括可执行文件在用户和内核模式下使用的 CPU 秒数。

所以,在上面的例子中,用户态的 CPU 时间是0.001 秒,内核态的 CPU 时间是0.002 秒。

现在,让我们重新运行相同的示例,但将time命令的标准错误重定向到文件:

$ time sleep 2 2> out.time
real    0m2.005s
user    0m0.002s
sys     0m0.002s

如我们所见,虽然我们将标准错误重定向到文件out.time,但time命令的输出仍然打印在终端窗口中。让我们检查一下out.time文件的内容:

$ cat out.time
$

尽管重定向了标准错误,但该文件为空。原因是time命令将2>out.time解释为**sleep命令的一部分,就好像我们要测量sleep 2 2>out.time命令的执行时间一样。由于命令sleep 2不打印任何内容,因此该文件为空。

3. time内置命令

3.1. 把time放在一个小组中

作为将time命令的输出正确重定向到文件的解决方案,我们可以使用花括号对time命令进行分组并重定向该组的输出:

$ { time sleep 2; } 2> out.time
$ cat out.time
real    0m2.002s
user    0m0.002s
sys     0m0.000s

现在,我们实现了我们的目标。**将time命令分组的原因是为了将重定向部分2> out.timetime命令隔离开来。**由于隔离,重定向部分不会作为传递给time命令的命令的一部分进行评估。

使用花括号对命令进行分组会在当前 shell 中运行花括号之间的命令。命令末尾的分号是必需的,否则会出现语法错误。

3.2. 防止所有错误到达我们的输出文件

上述解决方案有一个缺点。如果传递给time命令的可执行文件将某些内容打印到标准错误中,则time命令和可执行文件的输出将被写入同一个文件。例如,假设我们有一个脚本sleepy_hello_world.sh

#!/bin/bash
echo "Hello World to Standard Output" >&1
echo "Hello World to Standard Error" >&2
sleep 2

此脚本将第一个和第二个echo命令的输出分别打印到标准输出和标准错误。然后它会休眠两秒钟。

让我们通过用花括号将time命令分组来运行这个脚本:

$ { time sleepy_hello_world.sh; } 2> out.time
Hello World to Standard Output
$ cat out.time
Hello World to Standard Error
real    0m2.006s
user    0m0.005s
sys     0m0.001s

如我们所见,脚本中第二个echo命令的输出和time命令的输出被写入同一个文件。但是,我们可以通过将我们正在计时的命令的stderr转移到一个文件来分离输出:

$ { time sleepy_hello_world.sh 2> out.script; } 2> out.time
Hello World to Standard Output
$ cat out.script
Hello World to Standard Error
$ cat out.time
real    0m2.006s
user    0m0.002s
sys     0m0.004s

4. /usr/bin/time命令

到目前为止,我们使用的time命令是 Bash 提供的内置time命令。事实上,我们还可以使用另外一个time命令。

让我们使用type命令检查可用的time命令:

$ type -a time
time is a shell keyword
time is /bin/time
time is /usr/bin/time

第一个time命令*/bin/time是我们一直在使用的内置time*命令:

$ which time
/bin/time

作为内置时间命令的替代方法,我们可以使用第二个time 命令*/usr/bin/time*。它还将一个可执行文件作为参数,运行它并在最后显示执行时间:

$ /usr/bin/time -p sleep 2
real 2.00
user 0.00
sys 0.00

/usr/bin/time命令的*-p选项用于格式化输出。它还有另一个我们感兴趣的选项,–o选项。此选项采用文件名。*我们可以将/usr/bin/time命令的输出写入使用*–o*选项**指定的文件:

$ /usr/bin/time -p -o out.time sleep 2
$ cat out.time
real 2.00
user 0.00
sys 0.00

这就是我们想要的。传递给/usr/bin/time命令的可执行文件的输出也不会与/usr/bin/time*命令*的输出混合:

$ /usr/bin/time -p -o out.time sleepy_hello_world.sh
Hello World to Standard Output
Hello World to Standard Error
$ cat out.time
real 2.00
user 0.00
sys 0.00

我们可以使用man time查看*/usr/bin/time命令的手册页。我们可以使用help time获取有关内置time*命令的信息。