如何通过 Linux shell 命令关闭文件描述符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5987820/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to close file descriptor via Linux shell command
提问by Eric
In /proc/pid/fd/
, there are too many file descriptors. Can I use shell command to close these file descriptors?
在 中/proc/pid/fd/
,文件描述符太多。我可以使用 shell 命令关闭这些文件描述符吗?
回答by Ignacio Vazquez-Abrams
You can close a FD n
of the current process in bash as so:
您可以n
在 bash 中关闭当前进程的 FD ,如下所示:
exec n<&-
回答by MarkR
You can't just go around closing other processes' file descriptors and expect them to keep working.
您不能只是绕过关闭其他进程的文件描述符并期望它们继续工作。
Fix the program which has too many files open to make it open fewer. This may be a config change, or modifying the source etc. You can't just close the files for it.
修复打开文件过多的程序,使其打开较少。这可能是配置更改或修改源等。您不能只是关闭它的文件。
回答by Thomas Vander Stichele
You can definitely close fd's of other running processes as long as you have the permissions to do so.
只要您有权限,您绝对可以关闭其他正在运行的进程的 fd。
First, find the PID.
首先,找到PID。
Then, start gdb and attach to the process:
然后,启动 gdb 并附加到进程:
gdb -p 1598
Then, call the close system call on the fd you want to close:
然后,在要关闭的 fd 上调用 close 系统调用:
(gdb) call close(999)
= 0
If the file descriptor was a leaked one, then the program will never try to use it again anyway, and it shouldn't cause any issues. The program most likely has a bug, however.
如果文件描述符是泄露的,那么程序无论如何都不会再尝试使用它,也不应该引起任何问题。但是,该程序很可能存在错误。
回答by YSC
I've ran in a similar situation, but where gdb
was not an option since it disrupted the real-time constraints of my application and distorted my test.
我在类似的情况下运行过,但哪里gdb
不是一个选项,因为它破坏了我的应用程序的实时约束并扭曲了我的测试。
So I came up with a quick iptables
rule. Optional arguments put into square brackets ([ opt ]
).
所以我想出了一个快速的iptables
规则。置于方括号 ( [ opt ]
) 中的可选参数。
Find your destination address and port:
netstat --program [ --numeric-host --numeric-ports ] | grep [<pid>]/[<appname>]
$ netstat --program --numeric-ports | grep 8812/ tcp 0 0 ysc.xxx:54055 10.56.1.152:30000 ESTABLISHED 8812/my-application tcp 0 0 ysc.xxx:46786 postgres.xxx:5432 ESTABLISHED 8812/my-application tcp 0 0 ysc.xxx:36090 10.56.4.79:57000 ESTABLISHED 8812/my-application ... unix 2 [ ] DGRAM 7177020 8812/my-application
Here, I'd like to cut
10.56.4.79:57000
.Create an
iptables
rule to cut the socket:iptables -A OUTPUT [ --out-interface <if> --protocol <tcp|udp|unix> ] --destination <addr> --dport <port> --jump DROP
$ iptables -A OUTPUT --destination 10.56.4.79 --dport 57000 --jump DROP $
At this stage, your program can't send packets to the distant host. In most cases, the TCP connection is closed. You can proceed with your tests if there is some.
$ netstat --program --numeric-ports | grep 8812/ tcp 0 0 ysc.xxx:54055 10.56.1.152:30000 ESTABLISHED 8812/my-application tcp 0 0 ysc.xxx:46786 postgres.xxx:5432 ESTABLISHED 8812/my-application ... unix 2 [ ] DGRAM 7177020 8812/my-application
Remove the
iptables
rule:You just type in the same
iptables
rule replacing theA
by aD
.$ iptables -D OUTPUT --destination 10.56.4.79 --dport 57000 --jump DROP $
找到您的目的地地址和端口:
netstat --program [ --numeric-host --numeric-ports ] | grep [<pid>]/[<appname>]
$ netstat --program --numeric-ports | grep 8812/ tcp 0 0 ysc.xxx:54055 10.56.1.152:30000 ESTABLISHED 8812/my-application tcp 0 0 ysc.xxx:46786 postgres.xxx:5432 ESTABLISHED 8812/my-application tcp 0 0 ysc.xxx:36090 10.56.4.79:57000 ESTABLISHED 8812/my-application ... unix 2 [ ] DGRAM 7177020 8812/my-application
在这里,我想削减
10.56.4.79:57000
。创建一个
iptables
规则来切割套接字:iptables -A OUTPUT [ --out-interface <if> --protocol <tcp|udp|unix> ] --destination <addr> --dport <port> --jump DROP
$ iptables -A OUTPUT --destination 10.56.4.79 --dport 57000 --jump DROP $
在此阶段,您的程序无法向远程主机发送数据包。在大多数情况下,TCP 连接是关闭的。如果有的话,您可以继续进行测试。
$ netstat --program --numeric-ports | grep 8812/ tcp 0 0 ysc.xxx:54055 10.56.1.152:30000 ESTABLISHED 8812/my-application tcp 0 0 ysc.xxx:46786 postgres.xxx:5432 ESTABLISHED 8812/my-application ... unix 2 [ ] DGRAM 7177020 8812/my-application
删除
iptables
规则:您只需输入相同的
iptables
规则,A
用 a替换D
。$ iptables -D OUTPUT --destination 10.56.4.79 --dport 57000 --jump DROP $
回答by ks1322
@Thomas answer is valid only when debug information for close()
call is installed.
@Thomas 回答仅在close()
安装了呼叫的调试信息时才有效。
Without debug info installed, gdb refuses to call close()
:
没有安装调试信息,gdb 拒绝调用close()
:
(gdb) call close(3)
'close' has unknown return type; cast the call to its declared return type
The simplest way to make gdb call close()
in this case is to cast the call to close()
return type:
close()
在这种情况下进行 gdb 调用的最简单方法是将调用转换为close()
返回类型:
(gdb) call (int)close(3)
= 0
See gdb documentation:
请参阅 gdb文档:
Sometimes, a function you wish to call is missing debug information. In such case, GDB does not know the type of the function, including the types of the function's parameters. To avoid calling the inferior function incorrectly, which could result in the called function functioning erroneously and even crash, GDB refuses to call the function unless you tell it the type of the function.
For prototyped (i.e. ANSI/ISO style) functions, there are two ways to do that. The simplest is to cast the call to the function's declared return type.
有时,您希望调用的函数缺少调试信息。在这种情况下,GDB 不知道函数的类型,包括函数参数的类型。为了避免错误调用劣势函数,导致被调用函数运行错误甚至崩溃,GDB 拒绝调用该函数,除非你告诉它函数的类型。
对于原型(即 ANSI/ISO 风格)函数,有两种方法可以做到这一点。最简单的方法是将调用转换为函数声明的返回类型。