【问题标题】:How to redirect the output of the time command to a file in Linux?如何将 time 命令的输出重定向到 Linux 中的文件?
【发布时间】:2012-11-01 15:20:11
【问题描述】:

关于 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 来写入文件,但是 我的问题是关于没有这些选项的命令。

有什么建议吗?

【问题讨论】:

标签: linux bash time


【解决方案1】:

time 和您正在计时的命令放在一组括号中。

例如以下时间ls并将ls的结果和计时结果写入outfile

$ (time ls) > outfile 2>&1

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

$ (time ls) > ls_results 2> time_results

【讨论】:

  • 这里不需要引入子shell。
  • @sampson-chen 之所以有效,是因为 ls 不会向 stderr 写入任何内容,对吧?如果命令同时写入标准输出和标准错误,你将如何将“时间”的输出与要运行的命令的输出“分开”?
  • @January 评论可能更有用。使用括号启动一个新的 shell。要在不启动新 shell 的情况下对输出进行分组,请使用花括号。 { time ls }
【解决方案2】:

试试

{ time sleep 1 ; } 2> time.txt

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

或者使用

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

将“sleep”中的 STDERR 放入文件“sleep.stderr”,只有“time”中的 STDERR 放入“time.txt”

【讨论】:

  • 谢谢,这正好回答了我的问题。如果我理解正确的话,time命令的结果可以从stderr得到吗?
  • 可以,但必须将其放在大括号中,否则重定向将成为time 评估的命令的一部分。
  • @Daniel 您始终可以单独重定向内部命令输出(即 { time sleep 1 2> sleepStdErr.txt ; } 2> time.txt ),这只会让您获得时间输出。我不确定是否有办法独立获得它。
  • 如果您想将时间用于读取标准输出的 grep 之类的东西,请尝试 { time sleep 1; } 2>&1 | grep real。这会将标准错误发送到标准输出,然后 grep 可以读取。
  • 不要忘记';'关闭 '}' 之前的字符,没有它就行不通(我做了,而且......想知道为什么不工作:))
【解决方案3】:
&>out time command >/dev/null

在你的情况下

&>out time sleep 1 >/dev/null

然后

cat out

【讨论】:

  • 优雅的想法,但导致外壳不使用其内置命令。如果您没有安装真正的time 二进制文件,out 将包含类似bash: time: command not found 的内容。
  • 另外 GNU 时间的格式与内置的 bash 不一样,导致自动解析出现问题。
【解决方案4】:

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

time -o outfile command

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

【讨论】:

  • 这个,谢谢。你可以使用\time -o outfile command(带``)来使用GNU而不是内置的。
【解决方案5】:

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

{ 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

【讨论】:

    【解决方案6】:

    简单。 GNU time 实用程序有一个选项。

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

    /usr/bin/time -o time.txt sleep 1
    

    【讨论】:

    【解决方案7】:
    #!/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。

    【讨论】:

      【解决方案8】:

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

      { time sleep 1; } 2>&1 |  cat > time.txt
      

      【讨论】:

        【解决方案9】:

        如果你不想接触原始进程的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
        

        【讨论】:

          【解决方案10】:

          我最终使用了:

          /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 不一样

          【讨论】:

            【解决方案11】:

            如果您使用的是csh,您可以使用:

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

            例如:

            /usr/bin/time --output=outtime.txt -p csh -c 'cat file'
            

            【讨论】:

              【解决方案12】:

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

              var=`{ time <command> ; } 2>&1 1>/dev/null`
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-12-21
                • 1970-01-01
                • 2022-01-24
                相关资源
                最近更新 更多