Bash
關閉bash中的所有文件描述符
有沒有辦法關閉所有打開的文件描述符,而無需事先明確列出它們?
從字面上回答,關閉所有打開的文件描述符
bash
:for fd in $(ls /proc/$$/fd); do eval "exec $fd>&-" done
然而,這確實不是一個好主意,因為它會關閉 shell 輸入和輸出所需的基本文件描述符。如果這樣做,您執行的任何程序都不會在終端上顯示其輸出(除非它們
tty
直接寫入設備)。如果事實在我的測試中關閉stdin
(exec 0>&-
) 只會導致互動式 shell 退出。您實際上可能想要做的是關閉所有不屬於 shell 基本操作的文件描述符。這些是 0
stdin
, 1stdout
和 2stderr
。除此之外,一些 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
使用命令0
或1
您嘗試關閉的任何文件描述符)。**注意:**也使用 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-)
.