Shell

請幫助解釋這個 bash 輸出重定向

  • February 12, 2014

該腳本作為對Question的回答發布。我正在努力弄清楚發生了什麼。

result=$(
 {
   {
     ssh host app-status >&3 3>&-; echo "$?"
   } | {
     until read -t1 ret; do
       printf . >&2
     done
     exit "$ret"
   }
 } 3>&1
)

這是我的解釋,但我確定這是錯誤的。

  1. 外部{...} 3>&1: fd 3 作為標準輸出的副本打開
  2. 然後是管道的後半部分,’| { }` 無重定向
  3. 在讀取循環中,printf 的 stdout 與 stderr 重複,因此在 2.(上圖)中,所有輸出實際上都來自 stderr。
  4. 現在管道的前半部分{ ssh ... } |: ssh 的標準輸出被複製到 fd3 上(實際上是來自 1 的標準輸出。fd 3 被關閉,3>&-因此標準輸出重新打開到原來的位置,並通過管道傳輸到 2。
  5. 最後,echo只列印到標準輸出

所以我的問題(理解問題)是;這與 printf 到 stderr 的結果相同嗎?voodo重定向到 3 實際實現了什麼?這裡有什麼非同步的嗎?

在內部$(...),stdout (fd 1) 是一個管道。在管道的另一端,shell 讀取輸出並將其儲存到$result變數中。

與:$({ blah; } 3>&1)我們使 fd 3 和 1 都指向blah.

blahcmd1 | cmd2cmd1與fd 1 指向另一個管道(指向 的管道)同時cmd2啟動,但是我們不希望輸出進入該管道,我們希望它進入第一個管道,以便它可以儲存在.cmd1``cmd2``ssh``$result

所以我們有{ ssh >&3; echo "$?"; } | cmd2,所以只有echo輸出到管道cmd2ssh輸出 (fd 1) 轉到$result. ssh不需要 fd 3,我們在使用它設置 fd 1 ( 3>&-) 後將其關閉。

cmd2的輸入 (fd 0) 是第二個管道。在終止並在那裡輸出退出狀態之前,沒有任何東西寫入該管道(因為ssh正在寫入第一個管道) 。ssh``echo

所以在cmd2(作為until循環)中,read -t1實際上是在等待超時直到ssh退出。之後,會以fed byread的內容成功返回。$?``echo

引用自:https://unix.stackexchange.com/questions/113831