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

时间:2021-02-14 02:50:38

In /proc/pid/fd/, there are too many file descriptors. Can I use shell command to close these file descriptors?

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

4 个解决方案

#1


25  

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)
$1 = 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.

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

#2


4  

You can close a FD n of the current process in bash as so:

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

exec n<&-

#3


2  

I've ran in a similar situation, but where gdbwas 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])中。

  1. Find your destination address and port:

    找到您的目的地地址和端口:

    netstat --program [ --numeric-host --numeric-ports ] | grep [<pid>]/[<appname>]

    netstat --program [--numeric-host --numeric-ports] | grep [ ] / [ ]

    $ 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.

    在这里,我想削减10.56.4.79:57000。

  2. Create an iptables rule to cut the socket:

    创建一个iptables规则来切断套接字:

    iptables -A OUTPUT [ --out-interface <if> --protocol <tcp|udp|unix> ] --destination <addr> --dport <port> --jump DROP

    iptables -A OUTPUT [--out-interface --protocol ] - destination --dport --jump DROP

    $ iptables -A OUTPUT --destination 10.56.4.79 --dport 57000 --jump DROP
    $
    
  3. 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.

    在此阶段,您的程序无法将数据包发送到远程主机。在大多数情况下,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. Remove the iptables rule:

    删除iptables规则:

    You just type in the same iptables rule replacing the A by a D.

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

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

#4


-1  

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.

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

#1


25  

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)
$1 = 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.

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

#2


4  

You can close a FD n of the current process in bash as so:

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

exec n<&-

#3


2  

I've ran in a similar situation, but where gdbwas 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])中。

  1. Find your destination address and port:

    找到您的目的地地址和端口:

    netstat --program [ --numeric-host --numeric-ports ] | grep [<pid>]/[<appname>]

    netstat --program [--numeric-host --numeric-ports] | grep [ ] / [ ]

    $ 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.

    在这里,我想削减10.56.4.79:57000。

  2. Create an iptables rule to cut the socket:

    创建一个iptables规则来切断套接字:

    iptables -A OUTPUT [ --out-interface <if> --protocol <tcp|udp|unix> ] --destination <addr> --dport <port> --jump DROP

    iptables -A OUTPUT [--out-interface --protocol ] - destination --dport --jump DROP

    $ iptables -A OUTPUT --destination 10.56.4.79 --dport 57000 --jump DROP
    $
    
  3. 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.

    在此阶段,您的程序无法将数据包发送到远程主机。在大多数情况下,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. Remove the iptables rule:

    删除iptables规则:

    You just type in the same iptables rule replacing the A by a D.

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

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

#4


-1  

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.

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