如何从unix系统中的另一个进程关闭文件描述符

时间:2008-11-27 07:41:55

标签: bash unix file file-descriptor lsof

您可以使用命令 lsof 来获取所有正在运行的进程的文件描述符,但我想要做的是在不进入该进程的情况下关闭其中一些描述符。这可以在Windows上完成,因此您可以轻松取消阻止某些应用程序。

是否有任何命令或功能?

5 个答案:

答案 0 :(得分:76)

我不知道你为什么要这样做,但你应该能够使用gdb附加到进程,然后在fd上调用close()。例如:

在一个shell中:cat

在另一个shell中:

$pidof cat
7213

$gdb -p 7213

...
lots of output
...

(gdb)

现在告诉gdb执行close(0):

(gdb) p close(0)

$1 = 0

(gdb) c

Continuing.

Program exited with code 01.
(gdb)

在第一个shell中我得到了这个输出:

cat: -: Bad file descriptor

cat: closing standard input: Bad file descriptor

答案 1 :(得分:3)

我不这么认为,但是lsof会给你打开文件的进程的PID,所以你可以做的就是完全杀死进程或者至少发出一个信号让它退出。

答案 2 :(得分:2)

在Windows中,您可以使用程序来执行此操作,因为有人编写了一个程序,将设备驱动程序插入到运行的内核中来执行此操作。顺便说一下,执行此操作可能很危险,因为在关闭应用程序正在使用的句柄后,应用程序不知道句柄已关闭,并且当应用程序打开其他一些不相关的对象时,它不知道相同的句柄现在可能引用其他一些不相关的对象。你真的想尽快杀死破碎的应用程序。

在Linux中,你肯定可以使用相同的技术。编写一个将模块插入正在运行的内核的程序。与模块通信并告诉它关闭哪个句柄。这样做同样危险。

答案 3 :(得分:2)

我对此表示怀疑。文件描述符是进程本地的,stdout对所有进程都是1,但它们仍然引用了唯一的流。

对于您尝试解决的阻塞问题,或许更多细节会有用。

答案 4 :(得分:2)

在Unix上比在Windows上更少需要这样做。

在Windows上,大多数程序倾向于“锁定”(实际上拒绝共享)他们打开的文件,因此无法通过其他程序读取/写入/删除它们。

在Unix上,大部分时间都不会发生这种情况。 Unix上的文件锁定主要是建议性的,只会阻止其他锁定尝试,而不是正常的读/写/删除操作。您甚至可以删除进程的当前目录。

关于在Unix中正常使用的唯一情况是在尝试卸载文件系统时(根据挂载的文件系统的任何引用都可以阻止umount)。