Answers:
要从字面上回答,请关闭以下所有打开的文件描述符bash:
for fd in $(ls /proc/$$/fd); do
eval "exec $fd>&-"
done
但是,这实际上不是一个好主意,因为它将关闭外壳程序用于输入和输出所需的基本文件描述符。如果执行此操作,则您运行的所有程序都不会在终端上显示其输出(除非它们tty直接写入设备)。如果在我的测试中,事实关闭stdin(exec 0>&-)只会导致交互式外壳退出。
您实际上可能希望做的是关闭不属于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
还请注意,eval重定向变量中包含的文件描述符时,这是必需的,如果不bash进行扩展,则将变量视为命令的一部分(在这种情况下,它将尝试访问exec命令0或1尝试关闭的文件描述符)。
注意:同样使用glob代替ls(例如/proc/$$/fd/*)似乎会为glob打开一个额外的文件描述符,因此ls似乎是最好的解决方案。
有关的可移植性的更多信息/proc/$$/fd,请参见文件描述符链接的可移植性。如果/proc/$$/fd不可用,则使用替换掉的$(ls /proc/$$/fd)使用lsof(如果可用)将是$(lsof -p $$ -Ff | grep f[0-9] | cut -c 2-)。
/proc仅在Linux下可用。
/proc/PID/fd不是很轻便的话,那将是对的。但是说这/proc仅在Linux下可用并不是正确的说法。
<&-表格,是否有所不同/需要?
完全没有“ eval”的另一种方法是使用以下形式:
$ exec {var_a}>> file.txt
$ echo $var_a
10
$ ls -l /proc/self/fd/10
l-wx------ 1 0 0 64 Dec 11 18:32 /proc/self/fd/10 -> /run/user/0/tmp/file.txt
$ echo "aaaaa" >&$var_a
$ cat file.txt
aaaaa
$ exec {var_a}>&-
$ ls /proc/self/fd/10
ls: cannot access '/proc/self/fd/10': No such file or directory
不能。内核一次只能关闭一个FD,而bash没有FD的“组命令”。
for fd in $(ls -1 /proc/27343/fd); do echo exec $fd">&"-; done
删除echo和"之后的测试。
如果这不是用于shell本身,而是用于运行命令,则可以使用nohup。
>&-不能是参数;重定向是在参数扩展之前解析的。
exec {fd}>&-可以工作。