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}>&-
可以工作。