inux下有时需要查询某个文件被哪些进程调用,或者某个进程打开了哪些文件,今天介绍两个命令。
01fuser
可以显示出当前哪个程序在使用某个文件、挂载点、网络端口,并给出程序进程的PID等信息
如图fuser显示使用指定文件或者文件系统的用户、进程号、权限、命令。
权限类型有一下几种:
c——代表当前目录
e——将此文件作为程序的可执行对象使用
f——打开的文件,默认不显示
F——打开的文件,用于写操作,默认不显示
r——根目录
m——映射文件或者共享库
s——将此文件作为共享库
fuser命令常用选项:
-a 显示所有命令行中指定的文件,默认情况下被访问的文件才会被显示。
-c 和-m一样,用于POSIX兼容。
-k 杀掉访问文件的进程。如果没有指定-signal就会发送SIGKILL信号。
-i 杀掉进程之前询问用户,如果没有-k这个选项会被忽略。
-l 列出所有已知的信号名称。
-m name 指定一个挂载文件系统上的文件或者被挂载的块设备(名称name)。这样所有访问这个文件或者文件系统的进程都会被列出来。如果指定的是一个目录会自动转换成"name/",并使用所有挂载在那个目录下面的文件系统。
-n space 指定一个不同的命名空间(space).这里支持不同的空间文件(文件名,此处默认)、tcp(本地tcp端口)、udp(本地udp端口)。对于端口, 可以指定端口号或者名称,如果不会引起歧义那么可以使用简单表示的形式,例如:name/space (即形如:80/tcp之类的表示)。
-s 静默模式,这时候-u,-v会被忽略。-a不能和-s一起使用。
-signal 使用指定的信号,而不是用SIGKILL来杀掉进程。可以通过名称或者号码来表示信号(例如-HUP,-1),这个选项要和-k一起使用,否则会被忽略。
-u 在每个PID后面添加进程拥有者的用户名称。
-v 详细模式。输出似ps命令的输出,包含PID,USER,COMMAND等许多域,如果是内核访问的那么PID为kernel. -V 输出版本号。
-4 使用IPV4套接字,不能和-6一起应用,只在-n的tcp和udp的命名存在时不被忽略。
-6 使用IPV6套接字,不能和-4一起应用,只在-n的tcp和udp的命名存在时不被忽略。
- 重置所有的选项,把信号设置为SIGKILL.
下面举几个例子看一下:
查看某个端口被哪些进程占用
查看某个lib文件被哪些进程调用
查看某个可执行文件被调用
查看tcp80端口被调用
查看udp53端口被调用
另外fuser还可以直接发送信号给进程,可以查看下fuser支持的信号
比如直接关闭占用tail命令的进程
02lsof
列出当前系统打开文件
在linux环境下,任何事物都以文件的形式存在,通过文件不仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的
lsof输出中,每行显示一个打开的文件,若不指定条件,默认显示所有已打开的文件。
解释一下输出的每列的意义:
COMMAND:进程的名称
PID:进程标识符
USER:进程所有者
FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等 TYPE:文件类型,如DIR、REG等
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称
FD 列中的文件描述符cwd 值表示应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改,txt 类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序。
lsof需要访问核心内存和各种文件,所以必须y以root用户的身份运行。
lsof有相当多的选项,完全掌握之后基本可以替代netstat、ps之类的命令。
选项太多了,这里不对选项一一解释,直接上例子。
查看文件、设备占用
查看设备占用,在卸载文件系统的时候常用
同样可直接查看目录占用
查看某进程打开的文件
或者指定进程pid查看进程打开的文件
有时候需要删除某用户下的所有进程,只需要用-t参数就可以直接列出PID列。
还有很常用的就是查看端口的占用
同样可以通过进程名、pid查看
-i参数除了指定端口,还可以指定协议,TCP/UDP,甚至可以用@host来显示与指定主机的链接
也可以通过指定State状态来查看
lsof甚至可以用排除的方式查看除了某用户的所有进程,类似lsof -u ^root,只需要在用户前加^符号。