【发布时间】:2010-09-24 07:14:12
【问题描述】:
您可以使用命令 lsof 来获取所有正在运行的进程的文件描述符,但我想做的是关闭其中一些描述符而不进入该进程。这可以在 Windows 上完成,因此您可以轻松解锁某些应用程序。
有什么命令或功能吗?
【问题讨论】:
标签: bash unix file file-descriptor lsof
您可以使用命令 lsof 来获取所有正在运行的进程的文件描述符,但我想做的是关闭其中一些描述符而不进入该进程。这可以在 Windows 上完成,因此您可以轻松解锁某些应用程序。
有什么命令或功能吗?
【问题讨论】:
标签: bash unix file file-descriptor lsof
我不知道您为什么要这样做,但是您应该能够使用 gdb 附加到进程,然后在 fd 上调用 close()。示例:
在一个壳里:猫
在另一个外壳中:
$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
【讨论】:
p 会打印出一个表达式,因此 gdb 必须评估该表达式才能打印出其结果。因此close(0) 是一种无意调用,因为p 的实际目的不是引起副作用,而只是确定值。
我不这么认为,但是 lsof 会为您提供打开文件的进程的 PID,因此您可以做的是完全终止该进程或至少发送一个信号让它退出。
【讨论】:
在 Windows 中,您可以使用程序来执行此操作,因为有人编写了一个将设备驱动程序插入运行内核的程序来执行此操作。顺便说一句,这样做可能很危险,因为在您关闭一个损坏的应用程序正在使用的句柄后,应用程序不知道该句柄已关闭,并且当应用程序打开其他一些不相关的对象时它不知道同一个句柄现在可能引用其他一些不相关的对象。您真的想尽快杀死损坏的应用程序。
在 Linux 中,您当然可以使用相同的技术。编写一个程序,将模块插入到正在运行的内核中。与模块通信并告诉它关闭哪个句柄。这样做同样危险。
【讨论】:
我对此表示怀疑。文件描述符是进程本地的,stdout 对所有进程都是 1,但它们当然仍然引用唯一的流。
关于您要解决的阻塞问题,也许更详细的信息会很有用。
【讨论】:
在 Unix 上执行此操作的需要比在 Windows 上少得多。
在 Windows 上,大多数程序倾向于“锁定”(实际上拒绝共享)它们打开的文件,因此其他程序无法读取/写入/删除它们。
在 Unix 上,大多数情况下不会发生这种情况。 Unix 上的文件锁定主要是建议性的,只会阻止其他锁定尝试,而不是正常的读/写/删除操作。您甚至可以删除进程的当前目录。
在 Unix 中正常使用中出现这种情况的唯一情况是尝试卸载文件系统时(对已安装文件系统的任何引用都可能阻止卸载)。
【讨论】: