如何通过Linux shell命令关闭文件描述符

时间:2011-05-13 06:00:02

标签: linux shell file-descriptor

/proc/pid/fd/中,文件描述符太多。我可以使用shell命令关闭这些文件描述符吗?

5 个答案:

答案 0 :(得分:32)

只要您有权执行此操作,就可以关闭其他正在运行的进程的fd。

首先,找到PID。

然后,启动gdb并附加到进程:

gdb -p 1598

然后,在您要关闭的fd上调用close系统调用:

(gdb) call close(999)
$1 = 0

如果文件描述符是泄露的,那么程序永远不会尝试再次使用它,它不会导致任何问题。但是,该程序最有可能存在错误。

答案 1 :(得分:5)

您可以在bash中关闭当前进程的FD n,如下所示:

exec n<&-

答案 2 :(得分:2)

我遇到了类似的情况,但gdb不是一个选项,因为它破坏了我的应用程序的实时约束并扭曲了我的测试。

所以我提出了一个快速的iptables规则。 可选参数放在方括号([ opt ]

  1. 查找目的地址和端口

    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

  2. 创建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
    $
    
  3. 在此阶段,您的程序无法将数据包发送到远程主机。在大多数情况下, 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
    
  4. 删除iptables规则

    您只需输入相同的iptables规则,将A替换为D

    $ iptables -D OUTPUT --destination 10.56.4.79 --dport 57000 --jump DROP
    $
    

答案 3 :(得分:0)

@Thomas答案仅在安装了close()呼叫的调试信息时才有效。

未安装调试信息,gdb拒绝调用close()

(gdb) call close(3)
'close' has unknown return type; cast the call to its declared return type

在这种情况下,使gdb调用close()的最简单方法是将调用转换为close()返回类型:

(gdb) call (int)close(3)
$1 = 0

请参见gdb documentation

  

有时,您要调用的函数缺少调试信息。   在这种情况下,GDB不知道函数的类型,包括   函数参数的类型。避免叫劣等   功能不正确,可能导致调用函数   错误地运行甚至崩溃,GDB拒绝调用   函数,除非您告诉它函数的类型。

     

对于原型函数(即ANSI / ISO样式),有两种方法   去做。最简单的方法是将调用强制转换为该函数的已声明   返回类型。

答案 4 :(得分:-1)

你不能只是绕过关闭其他进程的文件描述符并期望它们继续工作。

修复打开了太多文件的程序,使其打开的次数减少。这可能是配置更改,或修改源等。您不能只关闭它的文件。