Gra*_*eme 18
从字面上回答,关闭所有打开的文件描述符bash:
for fd in $(ls /proc/$$/fd); do
eval "exec $fd>&-"
done
Run Code Online (Sandbox Code Playgroud)
然而,这真的不是一个好主意,因为它会关闭 shell 输入和输出所需的基本文件描述符。如果您这样做,您运行的所有程序都不会在终端上显示其输出(除非它们tty直接写入设备)。如果事实在我的测试中关闭stdin( exec 0>&-) 只会导致交互式 shell 退出。
您实际上可能想要做的是关闭所有不属于 shell 基本操作的文件描述符。它们是 0 代表stdin、1 代表stdout和 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
Run Code Online (Sandbox Code Playgroud)
另请注意,eval重定向包含在变量中的文件描述符时需要这样做,否则bash将扩展变量但将其视为命令的一部分(在这种情况下,它将尝试exec命令0或1您尝试关闭的任何文件描述符)。
注意:同样使用 glob 而不是ls(eg /proc/$$/fd/*) 似乎会为 glob 打开一个额外的文件描述符,所以ls这里似乎是最好的解决方案。
有关可移植性的更多信息/proc/$$/fd,请参阅文件描述符链接的可移植性。如果/proc/$$/fd不可用,则替换$(ls /proc/$$/fd), using lsof(如果可用)将是$(lsof -p $$ -Ff | grep f[0-9] | cut -c 2-)。
小智 6
在 Bash 的最新版本(4.1 及更高版本,2009 年及更高版本)中,您可以使用 shell 变量指定要关闭的文件描述符:
for fd in $(ls /proc/$$/fd/); do
[ $fd -gt 2 ] && exec {fd}<&-
done
Run Code Online (Sandbox Code Playgroud)
该功能已经在 Korn shell 中(自 1993 年以来?),但显然需要一些时间才能进入 Bash。
| 归档时间: |
|
| 查看次数: |
25674 次 |
| 最近记录: |