Bash

你什麼時候會使用額外的文件描述符?

  • April 30, 2020

我知道您可以創建一個文件描述符並將輸出重定向到它。例如

exec 3<> /tmp/foo # open fd 3.
echo a >&3 # write to it
exec 3>&- # close fd 3.

但是你可以在沒有文件描述符的情況下做同樣的事情:

FILE=/tmp/foo
echo a > "$FILE"

我正在尋找一個很好的例子,說明何時必須使用額外的文件描述符。

大多數命令都有一個輸入通道(標準輸入,文件描述符 0)和一個輸出通道(標準輸出,文件描述符 1),或者對它們自己打開的多個文件進行操作(因此您向它們傳遞文件名)。(這是標準錯誤(fd 2)的補充,它通常會一直過濾到使用者。)但是,有時有一個命令可以方便地從多個源或多個目標中過濾。例如,這是一個簡單的腳本,用於將文件中的奇數行與偶數行分開

while IFS= read -r line; do
 printf '%s\n' "$line"
 if IFS= read -r line; then printf '%s\n' "$line" >&3; fi
done >odd.txt 3>even.txt

現在假設您想對奇數行和偶數行應用不同的過濾器(但不要將它們重新組合在一起,這將是一個不同的問題,通常在 shell 中不可行)。在 shell 中,您只能將一個命令的標準輸出通過管道傳遞給另一個命令;要管道另一個文件描述符,您需要先將其重定向到 fd 1。

{ while … done | odd-filter >filtered-odd.txt; } 3>&1 | even-filter >filtered-even.txt

另一個更簡單的案例是過濾命令的錯誤輸出

exec M>&N為腳本的其餘部分將文件描述符重定向到另一個文件描述符(或直到另一個這樣的命令再次更改文件描述符)。exec M>&N和之間的功能有一些重疊somecommand M>&N。該exec表單更強大,因為它不必嵌套:

exec 8<&0 9>&1
exec >output12
command1
exec <input23
command2
exec >&9
command3
exec <&8

其他可能感興趣的例子:

還有更多範例:

PS 這是一個令人驚訝的問題,來自網站上使用通過 fd 3 重定向的最受好評的文章的作者!

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