[英]“$env” >| /dev/null , what is the redirection sign and the pipeline doing here?
[英]What is the extra set of () or {} doing to change what gets redirected to /dev/null?
我在 bash 上根據我對文件描述符重定向的理解做了一些測試,發現:
((echo STDOUT; echo STDERR >&2;) 3>&1 1>&2 2>&3 3>&-) 2> /dev/null
和
(echo STDOUT; echo STDERR >&2;) 3>&1 1>&2 2>&3 3>&- 2> /dev/null
給出了不同的結果。 第一個給出預期的STDERR
output,因為stdout
和stderr
fds 被交換,但第二個給出一個意想不到的STDOUT
output,就好像 fds 從來沒有交換過一樣。
這對我來說是令人驚訝的。 在這種情況下,我看不到額外的 par.netical 會做什么來更改 output。使用大括號具有相同的效果。
所以我認為的“預期”結果實際上是錯誤的,因為我錯誤地想象了正在發生的事情。 實際發生的是(-> 的左側是文件描述符(或者在最后一列的情況下是命令),右側是底層文件句柄 output 到的內容):
1 -> stdout 1 -. ,-> stdout 1 -. ,-> /dev/null echo STDOUT -> stderr
X X
2 -> stderr 2 -' '-> stderr 2 -' '-> stderr echo STDERR >&2 -> /dev/null
有了@JohnKugelman 的解釋,現在這就說得通了。
1 -> stdout 1 -> stdout 1 -. ,-> stdout echo STDOUT -> /dev/null
X
2 -> stderr 2 -> /dev/null 2 -' '-> /dev/null echo STDERR >&2 -> stdout
重定向將首先處理,即使它們是在命令之后編寫的。 這個事實很關鍵。 這意味着2> /dev/null
不是最后執行的。
盡管2> /dev/null
位於該行的末尾,但它實際上是在子 shell 啟動之前執行的。 (subshell) 2>/dev/null
實際上是2>/dev/null (subshell)
。 這意味着它在第一個示例中交換描述符之前執行,但在第二個示例中執行。
讓我們深入探討一下。
((echo STDOUT; echo STDERR >&2;) 3>&1 1>&2 2>&3 3>&-) 2> /dev/null
這相當於:
2>/dev/null (3>&1 1>&2 2>&3 3>&- (echo STDOUT; >&2 echo STDERR))
步驟是:
2> /dev/null
: fd 2 被重定向到/dev/null
。3>&1 1>&2 2>&3 3>&-
:交換 fds 1 和 2。echo STDOUT
:寫入 fd 1,即/dev/null
。>&2
:fd 1被重定向到fd 2,也就是原來的shell的stdout。echo STDERR
:寫入 fd 1,即標准輸出。(echo STDOUT; echo STDERR >&2;) 3>&1 1>&2 2>&3 3>&- 2> /dev/null
這相當於:
3>&1 1>&2 2>&3 3>&- 2>/dev/null (echo STDOUT; >&2 echo STDERR))
步驟是:
3>&1 1>&2 2>&3 3>&-
:交換 fds 1 和 2。2>/dev/null
:fd 2 被重定向到/dev/null
。echo STDOUT
:寫入 fd 1,這是原始 shell 的 stderr。>&2
:fd 1 被重定向到 fd 2,即/dev/null
。echo STDERR
:寫入 fd 1,即/dev/null
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.