【问题标题】:Send stderr and stdout to a function as variable and check type将 stderr 和 stdout 作为变量发送到函数并检查类型
【发布时间】:2018-07-01 02:28:48
【问题描述】:

我正在将脚本的输出重定向到我使用 2>&1 | MyFunction 编写的函数

这很好用。但是,我很难弄清楚如何确定正在传递的变量是 STDOUT 还是 STDERR in MyFunction

例如:

function MyFunction {
    while read line; do
        read IN
        echo "LOG: $IN" >> $LOG_FILE;
    done    
}

如果传递的变量是STDOUTSTDERR 的实例,是否有某种方法可以检查它,以便我可以根据它执行条件规则?

【问题讨论】:

    标签: bash


    【解决方案1】:

    管道将传送标准输出 (STDOUT) 数据。 2>&1 将标准错误(“2”)重定向到文件描述符“1”,即标准输出。

    这意味着以下行: myCommand 2>&1 | MyFunction 可以读作“运行myCommand,将标准错误重定向到标准输出,在输出上运行MyFunction(即标准错误+标准输出)”

    一旦你写了2>&1,就无法知道哪一行最初被发送到STDOUT或STDERR。

    【讨论】:

    • 嗯!你的最后一行可能是他正在寻找的。 :-)
    • 感谢您的回复。它让我对 2>&1 的用法有了更好的理解。
    【解决方案2】:

    不直接,不。如果您不需要与 Bash 以外的其他 shell 兼容,则可以在 Bash 中使用一些技巧来为每一行添加前缀;例如

    bash$ { perl -le 'print "oops"; die' 2> >(sed 's/^/stderr: /') > >(sed 's/^/stdout: /'); } 2>&1 | nl
     1  stdout: oops
     2  stderr: Died at -e line 1.
    

    如您所见,两个sed 进程的输出被重新组合成标准输出,然后作为标准输入通过管道传送到行编号程序nl。大括号将命令分组,以便最终重定向 2>&1 不会直接影响 Perl 进程。

    【讨论】:

      【解决方案3】:

      你可以用这个:

      # call the function like:
      # cmd | log err
      # cmd | log info    
      log() {
          type="${1}"
          while read -r line ; do
              if [ "${type}" = "err" ] ; then
                  echo "EE ${line}"
              else
                  echo "II ${line}"
              fi
          done
      }
      
      # Check this: https://stackoverflow.com/a/9113604/171318
      # Use another file descriptor to separate between stdout and stderr
      { stdbuf -eL -oL cmd 2>&3 | log info ; } 3>&1 1>&2 | log err
      # PS: ^ stdbuf makes sure that lines in output are in order
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-09
        • 1970-01-01
        • 2019-03-29
        • 2019-01-21
        • 2015-07-04
        • 2014-08-28
        • 2011-05-23
        • 2013-06-15
        相关资源
        最近更新 更多