240

只是一个关于 Linux 上计时程序的小问题: time 命令允许测量程序的执行时间:

[ed@lbox200 ~]$ time sleep 1

real    0m1.004s
user    0m0.000s
sys     0m0.004s

哪个工作正常。但是如果我尝试将输出重定向到一个文件,它就会失败。

[ed@lbox200 ~]$ time sleep 1 > time.txt

real    0m1.004s
user    0m0.001s
sys     0m0.004s

[ed@lbox200 ~]$ cat time.txt 
[ed@lbox200 ~]$ 

我知道选项 -o 有其他时间实现来写入文件,但我的问题是关于没有这些选项的命令。

有什么建议么 ?

4

12 回答 12

322

尝试

{ time sleep 1 ; } 2> time.txt

它将“时间”的 STDERR 和您的命令组合到 time.txt

或使用

{ time sleep 1 2> sleep.stderr ; } 2> time.txt

它将“睡眠”中的 STDERR 放入文件“sleep.stderr”中,并且只有“时间”中的 STDERR 进入“time.txt”

于 2012-11-13T06:56:53.217 回答
58

简单的。GNUtime实用程序有一个选项。

但是您必须确保您没有使用 shell 的内置time命令,至少内置命令bash不提供该选项!这就是为什么您需要提供该time实用程序的完整路径:

/usr/bin/time -o time.txt sleep 1
于 2015-10-16T00:08:29.820 回答
45

将您正在计时的命令包装time在一组括号中。

例如,下面的时间ls和时间的结果ls和计时的结果写入outfile

$ (time ls) > outfile 2>&1

或者,如果您想将命令的输出与捕获的输出分开time

$ (time ls) > ls_results 2> time_results
于 2012-11-13T06:55:55.217 回答
17

如果您关心命令的错误输出,您可以像这样将它们分开,同时仍然使用内置的 time 命令。

{ time your_command 2> command.err ; } 2> time.log

或者

{ time your_command 2>1 ; } 2> time.log

如您所见,该命令的错误转到一个文件(因为stderr用于time)。

不幸的是,您不能将其发送到另一个句柄(例如3>&2),因为在{...}

也就是说,如果你可以使用 GNU 时间,就按照@Tim Ludwinski 所说的去做。

\time -o time.log command
于 2015-04-06T00:08:50.330 回答
10

由于 'time' 命令的输出是错误输出,将其重定向为标准输出会更直观地进行进一步处理。

{ time sleep 1; } 2>&1 |  cat > time.txt
于 2016-07-06T18:35:28.407 回答
6

如果您使用的是 GNU time 而不是内置的 bash,请尝试

time -o outfile command

(注意:GNU 时间格式与内置的 bash 略有不同)。

于 2013-10-03T20:36:47.097 回答
4

我最终使用:

/usr/bin/time -ao output_file.txt -f "Operation took: %E" echo lol
  • 其中“a”是附加的
  • 其中“o”后面是要附加到的文件名
  • 其中“f”是具有类似 printf 语法的格式
  • 其中 "%E" 产生 0:00:00;时:分:秒
  • 我不得不调用 /usr/bin/time 因为 bash“时间”正在践踏它并且没有相同的选项
  • 我只是想将输出输出到文件,与 OP 不同
于 2018-01-09T19:42:06.663 回答
3
&>out time command >/dev/null

在你的情况下

&>out time sleep 1 >/dev/null

然后

cat out
于 2012-11-13T06:59:07.857 回答
2
#!/bin/bash

set -e

_onexit() {
    [[ $TMPD ]] && rm -rf "$TMPD"
}

TMPD="$(mktemp -d)"
trap _onexit EXIT

_time_2() {
    "$@" 2>&3
}

_time_1() {
    time _time_2 "$@"
}

_time() {
    declare time_label="$1"
    shift
    exec 3>&2
    _time_1 "$@" 2>"$TMPD/timing.$time_label"
    echo "time[$time_label]"
    cat "$TMPD/timing.$time_label"
}

_time a _do_something
_time b _do_another_thing
_time c _finish_up

这样做的好处是不生成子 shell,并且最终管道将其 stderr 恢复为真正的 stderr。

于 2016-01-21T18:03:00.767 回答
2

如果您不想接触原始进程的 stdout 和 stderr,可以将 stderr 重定向到文件描述符 3 并返回:

$ { time { perl -le "print 'foo'; warn 'bar';" 2>&3; }; } 3>&2 2> time.out
foo
bar at -e line 1.
$ cat time.out

real    0m0.009s
user    0m0.004s
sys     0m0.000s

您可以将其用于包装器(例如用于 cronjobs)来监控运行时:

#!/bin/bash

echo "[$(date)]" "$@" >> /my/runtime.log

{ time { "$@" 2>&3; }; } 3>&2 2>> /my/runtime.log
于 2017-08-15T14:21:04.453 回答
0

如果您想要shell 变量中的时间,那么这可以工作:

var=`{ time <command> ; } 2>&1 1>/dev/null`
于 2021-01-19T18:46:18.323 回答
0

如果您正在使用csh,您可以使用:

/usr/bin/time --output=outfile -p $SHELL  -c 'your command'

例如:

/usr/bin/time --output=outtime.txt -p csh -c 'cat file'
于 2018-05-17T15:16:16.673 回答