bash - redirection - standard output error to file




管道stdout和stderr到shell腳本中的兩個不同進程? (4)

使用其他文件描述符

{ command1 2>&3 | command2; } 3>&1 1>&2 | command3

您最多可以使用7個其他文件描述符:從3到9。
如果您想要更多解釋,請詢問,我可以解釋;-)

測試

{ { echo a; echo >&2 b; } 2>&3 | sed >&2 's/$/1/'; } 3>&1 1>&2 | sed 's/$/2/'

輸出:

b2
a1

生成兩個日誌文件:
1.只有stderr
2. stderrstdout

{ { { command 2>&1 1>&3; } | tee err-only.log; } 3>&1; } > err-and-stdout.log

如果commandecho "stdout"; echo "stderr" >&2 echo "stdout"; echo "stderr" >&2然後我們就可以測試它:

$ { { { echo out>&3;echo err>&1;}| tee err-only.log;} 3>&1;} > err-and-stdout.log
$ head err-only.log err-and-stdout.log
==> err-only.log <==
err

==> err-and-stdout.log <==
out
err

我做了一個pipline

 command1 | command2

因此,command1的stdout轉到command2,而command1的stderr轉到終端(或shell的stdout所在的地方)。

當stdout仍然轉到command2時,如何將command1的stderr傳遞給第三個進程( command3 )?


只需將stderr重定向到stdout即可

{ command1 | command2; } 2>&1 | command3

注意: commnd3也會讀取command2 stdout(如果有的話)。
為避免這種情況,您可以丟棄commnd2標準輸出:

{ command1 | command2 >/dev/null; } 2>&1 | command3

但是,為了保持command2 stdout(例如在終端中),
那麼請參考我的其他答案更複雜。

測試

{ { echo -e "a\nb\nc" >&2; echo "----"; } | sed 's/$/1/'; } 2>&1 | sed 's/$/2/'

輸出:

a2
b2
c2
----12


接受的答案導致stdoutstderr的逆轉。 這是一個保留它們的方法(因為谷歌搜索就是為了這個目的):

{ command 2>&1 1>&3 3>&- | stderr_command; } 3>&1 1>&2 | stdout_command

注意:

  • 3>&-是防止fd 3command繼承的必要條件。 (因為這會導致意外的結果,具體取決於內部的command 。)

零件說明:

  1. 外部第一部分:

    1. 3>&1 - fd 3 for { ... }設置為fd 1 (即stdout
    2. 1>&2 - { ... } fd 1設置為fd 2 (即stderr
    3. | stdout_command | stdout_command - fd 1 (是stdout )通過stdout_command傳送
  2. 內部部分從外部繼承文件描述符:

    1. 2>&1 - fd 2 for command設置為fd 1 (即外部的stderr
    2. 1>&3 - fd 1 for command設置為fd 3 (即外部部分為stdout
    3. 3>&- - fd 3 for command設置為空(即關閉
    4. | stderr_command | stderr_command - fd 1stderr )通過stderr_command傳送

例:

foo() {
    echo a
    echo b >&2
    echo c
    echo d >&2
}

{ foo 2>&1 1>&3 3>&- | sed -u 's/^/err: /'; } 3>&1 1>&2 | sed -u 's/^/out: /'

輸出:

out: a
err: b
err: d
out: c

a -> cb -> d順序總是不確定的,因為stderr_commandstdout_command之間沒有任何形式的同步。)





io-redirection