查询进程打开的文件[转]
fuser
有的时候我想要知道我的程序到底在这次启动过程中开启了多少文件,可以利用 fuser 来观察啦! 举例来说,你如果卸载时发现系统通知:『 device is busy 』,那表示这个文件系统正在忙碌中, 表示有某支程序有利用到该文件系统啦!那么你就可以利用 fuser 来追踪罗!fuser 语法有点像这样:
[root@www ~]# fuser [-umv] [-k [i] [-signal]] file/dir 选项与参数: -u :除了程序的 PID 之外,同时列出该程序的拥有者; -m :后面接的那个档名会主动的上提到该文件系统的最顶层,对 umount 不成功很有效! -v :可以列出每个文件与程序还有命令的完整相关性! -k :找出使用该文件/目录的 PID ,并试图以 SIGKILL 这个讯号给予该 PID; -i :必须与 -k 配合,在删除 PID 之前会先询问使用者意愿! -signal:例如 -1 -15 等等,若不加的话,默认是 SIGKILL (-9) 罗! 范例一:找出目前所在目录的使用 PID/所属帐号/权限 为何? [root@www ~]# fuser -uv . USER PID ACCESS COMMAND .: root 20639 ..c.. (root)bash
看到输出的结果没?他说『.』底下有个 PID 为 20639 的程序,该程序属於 root 且命令为 bash 。 比较有趣的是那个 ACCESS 的项目,那个项目代表的意义为:
- c :此程序在当前的目录下(非次目录);
- e :可被触发为运行状态;
- f :是一个被开启的文件;
- r :代表顶层目录 (root directory);
- F :该文件被开启了,不过在等待回应中;
- m :可能为分享的动态函式库;
那如果你想要查阅某个文件系统底下有多少程序正在占用该文件系统时,那个 -m 的选项就很有帮助了! 鸟哥的测试主机仅有分割出 /, /boot, /home ,所以无法进行测试。不过好在还有个 /proc 的虚拟文件系统, 让我们来了解一下这个 /proc 的文件系统有多少程序正在利用他吧!
范例二:找到所有使用到 /proc 这个文件系统的程序吧! [root@www ~]# fuser -uv /proc # 不会显示任何数据,因为没有任何程序会去使用 /proc 这个目录啊! # 会被用到的是 /proc 底下的文件啦!所以你应该要这样做: [root@www ~]# fuser -mvu /proc USER PID ACCESS COMMAND /proc: root 4289 f.... (root)klogd root 4555 f.... (root)acpid haldaemon 4758 f.... (haldaemon)hald root 4977 F.... (root)Xorg # 有这几支程序在进行 /proc 文件系统的存取喔!这样清楚了吗?
既然可以针对整个文件系统,那么能不能仅针对单一文件啊?当然可以罗!看一下底下的案例先:
范例三:找到 /var 底下属於 FIFO 类型的文件,并且找出存取该文件的程序 [root@www ~]# find /var -type p /var/gdm/.gdmfifo <==我们针对这玩意即可! /var/run/autofs.fifo-misc /var/run/autofs.fifo-net [root@www ~]# fuser -uv /var/gdm/.gdmfifo USER PID ACCESS COMMAND /var/gdm/.gdmfifo: root 4892 F.... (root)gdm-binary 范例四:同范例三,但试图删除该 PID?且『不要』删除喔! [root@www ~]# fuser -ki /var/gdm/.gdmfifo /var/gdm/.gdmfifo: 4892 Kill process 4892 ? (y/N) n
如何?很有趣的一个命令吧!透过这个 fuser 我们可以找出使用该文件、目录的程序,藉以观察的啦! 他的重点与 ps, pstree 不同。 fuser 可以让我们了解到某个文件 (或文件系统) 目前正在被哪些程序所利用!
lsof
相对於 fuser 是由文件或者装置去找出使用该文件或装置的程序,反过来说, 如何查出某个程序开启或者使用的文件与装置呢?呼呼!那就是使用 lsof 罗~
[root@www ~]# lsof [-aUu] [+d] 选项与参数: -a :多项数据需要『同时成立』才显示出结果时! -U :仅列出 Unix like 系统的 socket 文件类型; -u :后面接 username,列出该使用者相关程序所开启的文件; +d :后面接目录,亦即找出某个目录底下已经被开启的文件! 范例一:列出目前系统上面所有已经被开启的文件与装置: [root@www ~]# lsof COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME init 1 root cwd DIR 3,2 4096 2 / init 1 root rtd DIR 3,2 4096 2 / init 1 root txt REG 3,2 38620 1426405 /sbin/init ....(底下省略).... # 注意到了吗?是的,在默认的情况下, lsof 会将目前系统上面已经开启的 # 文件全部列出来~所以,画面多的吓人啊!您可以注意到,第一个文件 init 运行的 # 地方就在根目录,而根目录,嘿嘿!所在的 inode 也有显示出来喔! 范例二:仅列出关於 root 的所有程序开启的 socket 文件 [root@www ~]# lsof -u root -a -U COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME udevd 400 root 3u unix 0xedd4cd40 1445 socket auditd 4256 root 7u unix 0xedd4c380 9081 socket audispd 4258 root 0u unix 0xedd4c1e0 9080 socket # 注意到那个 -a 吧!如果你分别输入 lsof -u root 及 lsof -U ,会有啥资讯? # 使用 lsof -u root -U 及 lsof -u root -a -U ,呵呵!都不同啦! # -a 的用途就是在解决同时需要两个项目都成立时啊! ^_^ 范例三:请列出目前系统上面所有的被启动的周边装置 [root@www ~]# lsof +d /dev COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME init 1 root 10u FIFO 0,16 1147 /dev/initctl udevd 400 root 0u CHR 1,3 1420 /dev/null udevd 400 root 1u CHR 1,3 1420 /dev/null udevd 400 root 2u CHR 1,3 1420 /dev/null # 看吧!因为装置都在 /dev 里面嘛!所以罗,使用搜寻目录即可啊! 范例四:秀出属於 root 的 bash 这支程序所开启的文件 [root@www ~]# lsof -u root | grep bash bash 20639 root cwd DIR 3,2 4096 648321 /root bash 20639 root rtd DIR 3,2 4096 2 / bash 20639 root txt REG 3,2 735004 1199424 /bin/bash bash 20639 root mem REG 3,2 46680 64873 /lib/libnss_files-2.5.so ....(底下省略)....
这个命令可以找出您想要知道的某个程序是否有激活哪些资讯?例如上头提到的范例四的运行结果呢!
转自 http://vbird.dic.ksu.edu.tw/linux_basic/0440processcontrol_4.php