当前位置: 首页 > 科技观察

Linux下lsof命令详解

时间:2023-03-14 17:36:17 科技观察

本文转载自微信公众号《Linux开发那些事儿》,作者LinuxThings。转载此文请联系Linux开发那些事公众号.lsof是ListOpenFile的缩写。它主要用于获取有关进程打开的文件的信息。我们都知道,在Linux中,一切皆文件。lsof命令可以查看所有打开的文件,如:普通文件、目录、Specialblock文件、管道、socket套接字、设备、Unix域套接字等,同时也可以结合grep、ps命令进行更高级的搜索。lsof命令默认是没有安装的,它需要有root权限或者给普通的sudo权限才能使用。使用以下命令安装yuminstall-ylsoflsof。该命令有许多可选参数。本文根据自己的经验总结了一些比较常见和重要的用法。列出所有打开文件。lib/systemd/systemdsystemd1rootmemREG253,120064528340/usr/lib64/libuuid.so.1.3.0systemd1rootmemREG253,1265600532853/usr/lib64/libblkid.so.1.1.0systemd1rootmemREG253,190248525942/usr/lib64/libz.so.1.2.7systemd1rootmemREG253,1157424525955/usr/lib64/liblzma.so.5.2.2systemd1rootmemREG253,123968526159/usr/lib64/libcap-ng.so.0.0.0systemd1rootmemREG253,119896526135/usr/lib64/libattr.so.1.1.0systemd1rootmerootmREG253,119294852119294852EG253,1402384525931/usr/lib64/libpcre.so.1.2.0systemd1rootmemREG253,12156160由于lsof命令会输出很多信息,所以上面的例子使用lsof|more以页面显示命令的输出。在输出结果中,第一列的systemd进程ID为1,是一个守护进程。COMMAND、PID和USER列代表进程名称、进程ID和用户。FD列是一个文件描述符。以下是可能的类型和描述。FD描述cwd当前目录txttxt文件rtd根目录mem内存映射文件列TYPE是文件类型,以下是可能的值和描述TYPE描述DIR目录REG普通文件CHR字符a_inodeinode文件FIFO管道或套接字文件netlinknetworkunknown未知列DEVICE表示设备ID列SIZE/OFF表示进程大小列NODE表示文件的inode号列NAME指示列出指定用户打开的文件的路径或链接。使用-u选项列出指定用户已打开的文件。该选项后面可以跟多个用户名,每个用户名之间用空格分隔表示列显示指定用户打开的所有文件TYPE说明DIR目录REG普通文件CHR字符a_inodeInode文件FIFO管道或套接字文件在上面的例子中,lsof-utt命令的意思是列出用户tt打开的文件,从结果可以看出用户打开了文件/home/tt、/、/usr/bin/bash、/usr/bin/vim,/home/tt/.p.txt.swp。如果要排除指定用户打开过的文件,可以在用户名前加一个^符号。以下命令将列出除tt用户之外的所有用户打开的文件。在这种情况下,服务正在将日志写入日志文件。这时候正在写入的日志文件被不小心删除了。在上面的场景中,虽然日志文件被删除了,但是文件仍然是打开的。它仍然占用文件系统的空间,我们可以结合grep命令找出此类打开但被删除的文件[root@ecs-centos-7~]#lsof-utt|grepdeletedvim27813tt4uREG253,112288131167/home/tt/。p.txt.swp(deleted)在上面的例子中,使用lsof-utt|grepdeleted命令查看用户tt打开的删除文件。从结果可以看出,在向p.txt写入内容的时候,文件被删除了列出所有打开了的网络文件[root@ecs-centos-7~]#lsof-iCOMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEntpd567ntp18uIPv4126570t0UDPlocalhost:ntpntpd567ntp22uIPv5centosUD-0tp616-7.4-64bit-20200212:ntpdhclient651root6uIPv4145940t0UDP*:bootpcmaster960root13uIPv4157910t0TCPlocalhost:smtp(LISTEN)master960root14uIPv6157920t0TCPlocalhost:smtp(LISTEN)mysqld1053mysql13uIPv6151470t0TCP*:mysql(LISTEN)sshd1348root3uIPv4166980t0TCP*:ssh(LISTEN)listallIPV4/6networkfileslistallopenedipv4networkfiles[root@ecs-centos-7~]#ls-i4COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEntpd567ntp16uIPv4126510t0UDP*:ntpntpd567ntp18uIPv4126570t0UDPlocalhost:ntpntpd567ntp21uIPv4160940t0UDPecs-centos-7.4-64bit-20200212:ntpdhclient651root6uIPv4145940t0UDP*:bootpcmaster960root13uIPv4157910t0TCPlocalhost:smtp(LISTEN)sshd1348root3uIPv4166980t0TCP*:ssh(LISTEN)所有已经打开了的ipv6网络文件[root@ecs-centos-7~]#lsof-i6COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEntpd567ntp17uIPv6126520t0UDP*:ntpntpd567ntp19uIPv6126580t0UDPlocalhost:ntpntpd567ntp22uIPv6160950t0UDPecs-centos-7.4-64bit-20200212:ntpmaster960root14uIPv6157920t0TCPlocalhost:smtp(LISTEN)mysqld1053mysql13uIPv6151470t0TCP*:mysql(LISTEN)sshd1348root4uIPv6167000t0TCP*:ssh(LISTEN)列出在指定端口上打开的Thefileuseslsof-i:portnumbertogetallthefilesopenedonthespecifiedportnumber[root@ecs-centos-7~]#lsof-i:22COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEsshd1348root3uIPv4166980t0TCP*:ssh(LISTEN)sshd1348root4uIPv6167000t0TCP*:ssh(LISTEN)sshd27741root3uIPv44589580t0TCPecs-centos-7.4-64bit-20200212:ssh->113.118.121.220:42395(ESTABLISHED)sshd27819root3uIPv44592500t0TCPecs-centos-7.4-64bit-20200212:ssh->113.118.121.220:19807(ESTABLISHED)sshd27895root3uIPv44598280t0TCP上面的例子列出了22端口打开的所有文件,在服务器端开发中,往往会部署一个网关或者代理程序来与客户端通信。网关或代理程序需要开启固定端口用于客户端连接。如果客户端无法连接到网关或代理程序,我们可以使用上述命令查看网关或代理程序的端口是否打开,以排除网关因端口关闭而无法连接的情况。使用指定协议列出文件(TCP/UDP)使用lsof-iTCP/UDP列出使用TCP或UDP协议的文件sshd1704root4uIPv6135950t0TCP*:ssh(LISTEN)redis-serer1725root4uIPv4197730t0TCPlocalhost:6380(LISTEN)nc2067cgyx4uIPv4391670t0TCP*:60600(LISTEN)mysqld3020mysql4uIPv655146080t0TCP192.168.70.10:mysql->192.168.70.10:37084(ESTABLISHED)使用lsof-iTCP:3306列出使用theTCP协议和FILE[root@cghost8/home/cgyx]#lsof-iTCP:3306COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEmysqld3020mysql4uIPv655146080t0TCP192.168.70.10:mysql->192.168.70.10:37084using192.168.70.10:2listusing10:37084(ESTABLI-ls-ls-ls-ls了TCP协议并且端口范围为1到1024的文件[root@cghost8/home/cgyx]#lsof-iTCP:1-1024COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEsshd1704root3uIPv4135930t0TCP*:ssh(LISTEN)sshd1704root4uIPv6135950t0TCP*:ssh(LISTEN)cupsd1709root12uIPv6391480t0TCPlocalhost:ipp(LISTEN)cupsd1709root13uIPv4391490t0TCPlocalhost:ipp(LISTEN)smbd1824root35uIPv6176580t0TCP*:microsoft-ds(LISTEN)smbd1824root36uIPv6176590t0TCP*:netbios-ssn(LISTEN)smbd1824root37uIPv4176600t0TCP*:microsoft-ds(LISTEN)smbd1824root38uIPv4176610t0TCP*:netbios-ssn(LISTEN)列出目录中所有打开的文件Youcanusethelsofcommandtolistallopenfilesinthespecifieddirectory.Thereisadatadirectorywiththefollowingstructure:[root@ecs-centos-7tt]#treedata/data/├──dira│└──a.txt└──d.s1directory,2filesliststhefilesopenedinthedatadirectory[root@ecs-centos-7tt]#lsof+D./data/COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEbash28473rootcwdDIR253,14096131146./databash28502rootcwdDIR253,14096131172./data/diravim28530rootcwdDIR253,14096131172./data/diravim28530root4uREG253,112288131174./data/dira/.a.txt.swp[root@ecs-centos-7tt]#lsof+d./data/COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEbash28473rootcwdDIR253,14096131146./databash28502rootcwdDIR253,14096131172./data/diravim28530rootcwdDIR253,14096131172./data/dira在上面的示例中,+D和+d选项都列出了将在+D中打开的文件和目录子目录下的文件,+d选项只会列出当前目录下打开的文件。列出具有指定进程ID的已打开文件。进程ID是操作系统进程的唯一标识符。以下命令列出了进程ID为1053的相关文件,从结果中可以知道这个进程ID对应的进程是MySQL[root@ecs-centos-7~]#lsof-p1053COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEmysqld1053libsqlcwd4DIR2653,15507653mysqlmysqld1053mysqlrtdDIR253,140962/mysqld1053mysqltxtREG253,1251841448534935/usr/sbin/mysqldmysqld1053mysqlmemREG253,1209512659436/usr/lib64/mysql/plugin/validate_password.somysqld1053mysql1wREG253,1206658924771/var/log/mysqld.logmysqld1053mysql2wREG253,1206658924771/var/log/mysqld.log上述命令中,-p选项后面可以指定多个进程ID,每个进程ID用逗号隔开,如果要排除某个进程打开的文件,可以在进程ID前加上^符号lsof-p1,2,3,^4以上命令会列出进程1、进程2打开的所有文件,和进程3,同时忽略进程4打开的文件,杀死指定用户的所有进程。如上所述,列出指定用户打开的所有文件。我们可以配合使用kill命令来实现杀死指定用户所有进程的功能。具体命令如下kill-9`lsof-t-utt`上面命令中lsof-utt是列出所有tt用户打开的文件。添加-t选项后,表示结果只列出PID列,即进程ID列,其他列忽略。,前面的kill-9表示强制结束指定进程号