Bash

關閉bash中的所有文件描述符

  • October 30, 2021

有沒有辦法關閉所有打開的文件描述符,而無需事先明確列出它們?

從字面上回答,關閉所有打開的文件描述符bash

for fd in $(ls /proc/$$/fd); do
 eval "exec $fd>&-"
done

然而,這確實不是一個好主意,因為它會關閉 shell 輸入和輸出所需的基本文件描述符。如果這樣做,您執行的任何程序都不會在終端上顯示其輸出(除非它們tty直接寫入設備)。如果事實在我的測試中關閉stdin( exec 0>&-) 只會導致互動式 shell 退出。

您實際上可能想要做的是關閉所有不屬於 shell 基本操作的文件描述符。這些是 0 stdin, 1stdout和 2 stderr。除此之外,一些 shell 似乎還預設打開了其他文件描述符。例如bash,您有 255 個(也用於終端 I/O),而dash我有 10 個,它指向而不是終端正在使用/dev/tty的特定tty/設備。pts要關閉除 0、1、2 和 255 以外的所有內容bash

for fd in $(ls /proc/$$/fd); do
 case "$fd" in
   0|1|2|255)
     ;;
   *)
     eval "exec $fd>&-"
     ;;
 esac
done

另請注意,eval在重定向變數中包含的文件描述符時需要這樣做,否則bash將擴展變數但將其視為命令的一部分(在這種情況下,它將嘗試exec使用命令01您嘗試關閉的任何文件描述符)。

**注意:**也使用 glob 而不是ls(eg /proc/$$/fd/*) 似乎會為 glob 打開一個額外的文件描述符,所以ls這裡似乎是最好的解決方案。

更新

有關可移植性的更多資訊/proc/$$/fd,請參閱文件描述符連結的可移植性。如果/proc/$$/fd不可用,則替換$(ls /proc/$$/fd), 使用lsof(如果可用)將是$(lsof -p $$ -Ff | grep f[0-9] | cut -c 2-).

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