【问题标题】:Force `tee` to run for every command in a shell script?强制 `tee` 为 shell 脚本中的每个命令运行?
【发布时间】:2011-05-01 12:46:15
【问题描述】:

我想要一个脚本,其中所有命令都tee'd 到日志文件。

现在我正在运行脚本中的每个命令:

<command> | tee -a $LOGFILE

有没有办法强制 shell 脚本中的每个命令通过管道传输到 tee

我不能强制用户在运行 脚本 时添加适当的 teeing,并且希望确保它正确记录,即使调用用户没有添加记录他们自己的调用。

【问题讨论】:

    标签: linux bash logging shell tee


    【解决方案1】:

    您可以在脚本中进行包装:

    #!/bin/bash
    {
    echo 'hello'
    some_more_commands
    echo 'goodbye'
    } | tee -a /path/to/logfile
    

    编辑:

    这是另一种方式:

    #!/bin/bash
    exec > >(tee -a /path/to/logfile)
    echo 'hello'
    some_more_commands
    echo 'goodbye'
    

    【讨论】:

    • 我喜欢这个 - 没想过使用括号
    • 使用exec &gt; &gt;(tee -a /path/to/logfile) 2&gt;&amp;1 也可以将错误输出到文件中,以防您记录一个文件中发生的所有事情。 -a 是附加的,但您也可以删除它以每次都在文件上重新开始。
    【解决方案2】:

    为什么不公开一个简单的包装器:

    /path/to/yourOriginalScript.sh | tee -a $LOGFILE
    

    您的用户不应执行(甚至不知道)yourOriginalScript.sh

    【讨论】:

      【解决方案3】:

      假设您的脚本不采用 --tee 参数,您可以这样做(如果您使用该参数,只需将下面的 --tee 替换为您不使用的参数):

      #!/bin/bash
      
      if [ -z "$1" ] || [ "$1" != --tee ]; then
        $0 --tee "$@" | tee $LOGFILE
        exit $?
      else
        shift
      fi
      # rest of script follows
      

      这只是让脚本自己重新运行,使用特殊参数--tee 来防止无限递归,将其输出通过管道传输到tee

      【讨论】:

      • 也可以使用exec 来不分叉额外的进程:if ...; then exec $0 --tee "$@"; else; shift; fi(不再需要退出)...
      【解决方案4】:

      有些方法是创建所有用户调用自己的脚本的运行器脚本“run_it”。

      run_it my_script
      

      所有的魔法都会在内部完成,例如可能看起来像这样:

      LOG_DIR=/var/log/
      $@ | tee -a  $LOG_DIR/
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-25
        • 2013-08-21
        • 1970-01-01
        • 1970-01-01
        • 2011-07-14
        • 2015-04-19
        相关资源
        最近更新 更多