代码之家  ›  专栏  ›  技术社区  ›  jchook

将stdout+stderr发送到文件,并将stderr+任意状态消息发送到控制台

  •  1
  • jchook  · 技术社区  · 7 年前

    我仔细研究了大概20个问题,想找到一个解决这个问题的办法,但没有成功。这似乎是一项共同的任务。

    我对bash脚本有以下要求:

    1. 发送 stdout log.out ,不是控制台
    2. stderr 注销 和控制台
    3. 注销 ?)

    目前,我正试图实现以下目标:

    #!/bin/bash
    
    > log.out
    
    exec 3>&1 4>&2
    trap 'exec 2>&4 1>&3' 0 1 2 3
    exec 1>>log.out 2>&1
    
    # Test
    echo "status goes to console" >&3
    echo "stderr goes to file + console" >&2
    echo "stdout goes to file"
    

    我对这段代码的理解大致是。。。

    1. 当脚本退出时(可能不必要)重置它们?
    2. 将stdout发送到log.out,并将stderr也发送到那里

    除了错误不会显示在控制台上之外,这一点非常有效。

    所以,我想,我只是猫 /dev/stderr &3 在一个单独的bg过程中,在第2行下面添加了这一行 exec :

    cat /dev/stderr >&3 &
    

    我不明白为什么,但这也会将stdout发送到&3,因此我的控制台显示:

    echoes goes to console
    stderr goes to file + console
    stdout goes to file
    

    任何帮助都非常感谢。


    谢谢!

    exec 3>&1 4>&2
    trap 'exec 2>&4 1>&3' 0 1 2 3
    exec 1>log.out 2> >(tee /dev/tty >&1)
    

    缺点是消息在日志文件中的显示顺序确实不正确。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Charles Duffy    7 年前

    假设您拥有bash 4.1或更高版本:

    # make copies of orig stdout, /dev/tty, and our log file FDs
    exec {orig_stdout_fd}>&1
    exec {tty_fd}>/dev/tty
    exec {file_fd}>log.out
    
    # ...and set them up however you wish, using ''tee'' for anything that goes two places
    exec >&$file_fd                                  # redirect stdout only to the log file
    exec 2> >(tee /dev/fd/"$tty_fd" >&$file_fd)      # redirect stderr to both sinks
    

    请注意,写入stderr要比写入stdout花费更长的时间(因为它们要经过FIFO),因此排序可能会丢失。

    推荐文章