标准输出的标准错误 - 除了重定向之外还有其他选项吗?

-5 stdout stderr

我对standard errorstandard output...的了解非常有限

一种常见的方法是重定向standard errorstandard output. 这是否意味着错误(通常会发生standard error)永远不会standard error因为重定向而发生?

如果这是真的,是否有任何方法可以复制standard error、重定向副本standard output并让原始文件按照standard error预期的方式定向到?

Ljm*_*art 8

在我使用 Unix 的早期,有人向我解释说管道的工作原理就像管道一样。

一个过程基本上有 3 个连接点用于您的填充:

           stdin
             |
          +--+--+
          | pgm |
          ++---++
           |   |
      stdout   stderr
Run Code Online (Sandbox Code Playgroud)

所以,当你这样做时cat | grep pattern,你会得到

         stdin
           |
        +--+--+
        | cat |
        ++---++
   stdout|   |stderr
         |   \
    stdin|    \
     +------+  |
     | grep |  |
     +-+---++  |
 stdout|   |   |
       |   \__ |
       |      \|
       |       |stderr
Run Code Online (Sandbox Code Playgroud)

(在那些日子里,都是ASCII图形......)

当您将 stderr 重定向到 stdout 时,如 中所示pgm 2>&1,图片变为:

    stdin |
          |
       +--+--+
       | pgm |
       ++---++
  stdout|   |stderr
        |   /
        |  /
        | /
        |/
        |
Run Code Online (Sandbox Code Playgroud)

从理论上讲,您可以通过这种方式进行大量管道工作。例如:将awk '{print;print > "/dev/stderr"}'stdin 复制到 stdout 和 stderr。

然而,它很快变得非常混乱。有关详细信息,请参阅 bash 手册。

注意: pgm = 上图中的程序。

编辑:为了好玩,我使用简单的 shellscripts 尝试了一些更复杂的管道。

generate.sh

echoerr() { echo "$@" 1>&2; }
for i in 1 2 3 4 5 6 ; do
        echo "STDOUT $i"
        echoerr "STDERR $i"
done
Run Code Online (Sandbox Code Playgroud)

copytee.sh

#!/bin/bash
echoerr() { echo "$@" 1>&2; }
while read line; do
        echo "stdout $line"
        echoerr "stderr $line"
done
Run Code Online (Sandbox Code Playgroud)

(注意 copytee ads 小写和 generate 添加大写)

要获得高级形式的重定向,请bash generate.sh 2> >(bash copytee.sh ) 提供以下输出:

STDOUT 1
STDOUT 2
STDOUT 3
STDOUT 4
STDOUT 5
STDOUT 6
stdout STDERR 1
stderr STDERR 1
stdout STDERR 2
stderr STDERR 2
stdout STDERR 3
stderr STDERR 3
stdout STDERR 4
stderr STDERR 4
stdout STDERR 5
stderr STDERR 5
stdout STDERR 6
stderr STDERR 6
Run Code Online (Sandbox Code Playgroud)

这正是您所要求的。