fuser:由文件找出占用该文件的程序

有的时候我想要知道我的程序到底在这次启动过程中开启了多少文件,可以利用 fuser 来观察!

举例来说,你如果卸载时发现系统通知:『 device is busy 』,那表示这个文件系统正在忙碌中, 表示有某支程序正在使用该文件系统!那么你就可以利用 fuser 来追踪。

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/所属帐号/权限

1
fuser -uv .
1
2
             USER   PID ACCESS  COMMAND
/home/zhang: zhang 3194 ..c.. (zhang)bash

看到输出的结果没?他说『.』底下有个 PID 为 3194 的程序,该程序属于 zhang 且命令为 bash 。 比较有趣的是那个 ACCESS 的项目,那个项目代表的意义为:

  • -c :此程序在当前的目录下(非次目录);
  • -e :可被触发为运行状态;
  • -f :是一个被开启的文件;
  • -r :代表顶层目录 (root directory);
  • -F :该文件被开启了,不过在等待回应中;
  • -m :可能为分享的动态函式库;

那如果你想要查阅某个文件系统底下有多少程序正在占用该文件系统时,那个 -m 的选项就很有帮助了! 我的测试主机仅有分割出 /, /boot, /home ,所以无法进行测试。

不过好在还有个 /proc 的虚拟文件系统, 让我们来了解一下这个 /proc 的文件系统有多少程序正在利用他吧!

范例:找到所有使用到 /proc 这个文件系统的程序!

1
fuser -uv /proc  #不加-m
1
2
       USER    PID ACCESS COMMAND
/proc: root kernel mount (root)/proc
1
fuser -muv /proc   #加-m
1
2
3
4
5
6
7
8
9
10
 USER PID ACCESS COMMAND
/proc: root kernel mount (root)/proc
root 1 .rce. (root)systemd
root 2 .rce. (root)kthreadd
root 3 .rce. (root)ksoftirqd/0
root 4 .rce. (root)kworker/0:0
root 5 .rce. (root)kworker/0:0H
root 6 .rce. (root)kworker/u256:0
root 7 .rce. (root)migration/0
......

通过这个 fuser 我们可以找出使用该文件、目录的程序,藉以观察了! 他的重点与 ps, pstree 不同。 fuser 可以让我们了解到某个文件 (或文件系统) 目前正在被哪些程序所利用!

lsof :列出被程序占用的文件名

相对于 fuser 是由文件或者文件系统去找出使用该文件或文件系统的程序,反过来说, lsof 就是查出某个程序开启或者使用的文件与文件系统。

lsof [-aUu] [+d]

常用选项:

  • -a :多项数据需要『同时成立』才显示出结果时!
  • -U :仅列出 Unix like 系统的 socket 文件类型;
  • -u :后面接 username,列出该使用者相关程序所开启的文件;
  • +d :后面接目录,亦即找出某个目录底下已经被开启的文件!

范例:列出目前系统上面所有已经被开启的文件与装置:

1
lsof
1
2
3
4
5
6
7
8
9
COMMAND PID  TID USER   FD    TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd unknown /proc/1/cwd (readlink: Permission denied)
systemd 1 root rtd unknown /proc/1/root (readlink: Permission denied)
systemd 1 root txt unknown /proc/1/exe (readlink: Permission denied)
systemd 1 root NOFD /proc/1/fd (opendir: Permission denied)
kthreadd 2 root cwd unknown /proc/2/cwd (readlink: Permission denied)
kthreadd 2 root rtd unknown /proc/2/root (readlink: Permission denied)
kthreadd 2 root txt unknown /proc/2/exe (readlink: Permission denied)
......