如何在多个命令上运行时间并将时间输出写入文件?

Kar*_*lek 77 shell command time-utility

我想运行time命令来测量几个命令的时间。

我想做的是:

  • 测量所有这些加在一起的运行时间
  • 将time输出写入文件
  • STDERR从我正在测量的命令中写入STDERR

我确实不希望做的是

  • 将几个命令写入一个单独的脚本(为什么?因为所有这些都已经是我以编程方式生成的脚本,创建另一个临时脚本会比我想要的更混乱)

到目前为止我尝试过的:

/usr/bin/time --output=outtime -p echo "a"; echo "b";

不起作用,time仅在第一个上运行。

/usr/bin/time --output=outtime -p ( echo "a"; echo "b"; )

不起作用,(是意外令牌。

/usr/bin/time --output=outtime -p { echo "a"; echo "b"; }

不起作用,“没有这样的文件或目录”。

/usr/bin/time --output=outtime -p ' echo "a"; echo "b";'

不起作用,“没有这样的文件或目录”。

time ( echo "a"; echo "b"; ) 2>outtime

不起作用,因为它全部重定向STDERR到outtime; 我只想要time那里的输出。

而且当然,

time --output=outime echo "a";

不起作用,因为--output=outime: command not found.

我该怎么做?

Jim*_*ris 104

使用sh -c 'commands'的命令,例如:

/usr/bin/time --output=outtime -p sh -c 'echo "a"; echo "b"'
Run Code Online (Sandbox Code Playgroud)

  • 较短的版本:`time -p sh -c 'echo "a"; 回声“b”'` (3认同)

Mar*_* T. 19

不是正确答案,但与问题非常相关。
需要获取多个程序组合括号的计时统计信息。用分号分隔命令;或 &&,如果 command2 应该只运行,当 command1 退出时没有错误:

time ( command1 ; command2 )

time ( command1 && command2 )
Run Code Online (Sandbox Code Playgroud)

  • 这很好。更好的是,在命令之间使用 && - 就像`time ( command1 && command2 )` 这样,如果第一个命令失败;它不会继续执行另一个。 (3认同)
  • @bikashg 这在很大程度上取决于您想要运行的内容。就我而言,我使用 `|` 是因为我在三个命令之间进行管道传输。 (2认同)

ang*_*gus 9

尝试这个:

% (time ( { echas z; echo 2 } 2>&3 ) ) 3>&2 2>timeoutput
zsh: command not found: echas
2
% cat timeoutput                                
( { echas z; echo 2; } 2>&3; )  0.00s user 0.00s system 0% cpu 0.004 total
Run Code Online (Sandbox Code Playgroud)

解释:

首先,我们必须找到一种方法来重定向time. 由于time是内置的 shell,所以它以完整的命令行作为要测量的命令,包括重定向。因此,

% time whatever 2>timeoutput
whatever 2> timeoutput  0.00s user 0.00s system 0% cpu 0.018 total
% cat timeoutput 
zsh: command not found: whatever
Run Code Online (Sandbox Code Playgroud)

[注意:janos 的评论暗示 不是这种情况bash。] 我们可以time通过time在子shell 中运行然后重定向该子shell的输出来实现的输出的重定向。

% (time whatever) 2> timeoutput
% cat timeoutput 
zsh: command not found: whatever
whatever  0.00s user 0.00s system 0% cpu 0.018 total
Run Code Online (Sandbox Code Playgroud)

现在我们已经成功地重定向了 的输出time,但是它的输出与我们正在测量的命令的错误输出混合在一起。为了将两者分开,我们使用了一个额外的文件描述符。

在“外面”,我们有

% (time ... ) 3>&2 2>timeout
Run Code Online (Sandbox Code Playgroud)

这意味着:写入文件描述符 3 的任何内容都将输出到文件描述符 2(标准错误)现在正在输出(终端)的相同位置。然后我们将标准错误重定向到文件timeout.

所以现在我们有了:写入 stdout 和 fd 3 的所有内容都将进入终端,写入 stderr 的所有内容都将进入文件。剩下的就是将测量命令的 stderr 重定向到 fd 3。

% (time whatever 2>&3) 3>&2 2>timeout
Run Code Online (Sandbox Code Playgroud)

现在,为了使时间测量多个命令,我们需要在(其他!)子shell(括号内)中运行它们。并且要将所有它们的错误输出重定向到 fd 3,我们需要将它们分组在大括号内。

所以,最后,我们到达:

% (time ( { whatever; ls } 2>&3 ) ) 3>&2 2>timeoutput
Run Code Online (Sandbox Code Playgroud)

就是这样。