Io-Redirection

不理解此命令中的重定向?

  • July 10, 2017

我在這裡找到了一個神奇的命令

./my.sh 3>all 1> >(tee out >&3) 2> >(tee err >&3)

我在某些地方感到困惑:

  1. 是否3>all意味著為 file 設置文件描述符 3 all
  2. 做什麼1> >2> >?根據我的理解,命令應該是./my.sh 3>all 1>(tee out >&3) 2>(tee err >&3). 但這不起作用。
  3. 為什麼不(tee err >&3)覆蓋文件all

這是我的my.sh

#!/bin/bash

echo myecho
ls dflj

您可以在 bash 手冊頁中的Process substitution下閱讀有關此語法的資訊:

>(list). 程序列表執行,其輸出連接到 /dev/fd 中的某個文件。作為擴展的結果,此文件的名稱作為參數傳遞給目前命令。

查看此命令的輸出,它不執行任何重定向:

echo >(echo hi >/tmp/a) >(echo lo >/tmp/b)

它是(在我的系統上):

/dev/fd/63 /dev/fd/62

所以你必須讀1> >(...)1>and >(...)。第二部分被替換/dev/fd/63,然後1> /dev/fd/63我們將標準輸出重定向到文件描述符 63。

bash>(...)在一個單獨的程序中執行命令,並將該程序的標準輸入連接到文件描述符 63。看看這個例子:

set -x
echo hello > >(cat -n)

迴聲的標準輸出通過管道傳輸到的輸入中cat -n,您將得到:

+ echo hello
++ cat -n
1  hello

也許您缺少的是,當您擁有一個文件的文件描述符(fd),然後分叉該程序(bash 正在使用該程序>(...))時,您可以在新程序中繼承相同的 fd。所以這2個程序共享相同的fd。此外,一個 fd 只有一個文件偏移量,因此如果程序 1 向 fd 寫入 3 個字元,則偏移量從 0 移動到 3。如果程序 2 然後向 fd 寫入 5 個字元,則數據位於偏移量 3並且偏移量變為 8。如果程序 1 寫入另一個字元,它將被放置在偏移量 8 處,依此類推。這就是tee您問題中的兩個命令如何設法寫入同一個文件all而不會相互覆蓋。

using>&3不會創建新的 fd;它只是關閉目前的標準輸出 fd 1,然後將 fd 3 重新編號為 fd 1。因此,即使每個程序現在看到的數字不同,這兩個程序仍然只有一個 fd(請參閱man dup2底層系統呼叫)。

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