簡體   English   中英

額外的一組 () 或 {} 用來改變重定向到 /dev/null 的內容是什么?

[英]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,因為stdoutstderr 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))

步驟是:

  1. 2> /dev/null : fd 2 被重定向到/dev/null
  2. 外部子外殼啟動。
  3. 3>&1 1>&2 2>&3 3>&- :交換 fds 1 和 2。
  4. 內部子外殼啟動。
  5. echo STDOUT :寫入 fd 1,即/dev/null
  6. >&2 :fd 1被重定向到fd 2,也就是原來的shell的stdout。
  7. 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))

步驟是:

  1. 3>&1 1>&2 2>&3 3>&- :交換 fds 1 和 2。
  2. 2>/dev/null :fd 2 被重定向到/dev/null
  3. 子外殼啟動。
  4. echo STDOUT :寫入 fd 1,這是原始 shell 的 stderr。
  5. >&2 :fd 1 被重定向到 fd 2,即/dev/null
  6. echo STDERR :寫入 fd 1,即/dev/null

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM