title: lsof命令 date: 2015-08-21 10:37:24 tags: [Command,Tools]

**简介:**lsof命令既(list open files)Lsof 是遵从Unix 哲学的典范,它只做一件事情,并且做的相当完美——它可以列出某个进程打开的所有文件信息。打开的文件可能是普通的文件,目录,NFS文件,块文件,字符文件,共享库,常规管道,明明管道,符号链接,Socket流,网络Socket,UNIX域Socket,以及其它更多。因为Unix系统中几乎所有东西都是文件,你可以想象lsof该有多有用。

安装

  • yum安装
    1
    
    yum install lsof -y
    
  • 源码安装
    1
    2
    3
    4
    5
    6
    
    wget http://down1.chinaunix.net/distfiles/lsof_4.76.tar.gz
    tar -zxvf lsof.tar.gz
    cd lsof_4.78
    tar xvf lsof_4.78_srv.tar
    ./configure lunux
    make
    

例子

  • lsof 不加参数的输出,是列出所有进程打开的所有文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    arvon@Mo:~> lsof
    lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /root/.gvfs
        Output information may be incomplete.
    COMMAND     PID         USER        FD      	TYPE 		DEVICE 			SIZE/OFF   NODE 	NAME
    进程的名称	进程标识符	进程所有者	文件描述符	文件类型	指定磁盘的名称		文件的大小 索引节点 打开文件的确切名称
    init          1       root  cwd   unknown                        /proc/1/cwd (readlink: Permission denied)
    init          1       root  rtd   unknown                        /proc/1/root (readlink: Permission denied)
    init          1       root  txt   unknown                        /proc/1/exe (readlink: Permission denied)
    init          1       root NOFD                                  /proc/1/fd (opendir: Permission denied)
    
  • lsof /path/to/file /path/to/file2 找出谁在使用某个文件,可一次指定多个文件
    1
    2
    3
    4
    5
    6
    7
    
    arvon@Mo:~> lsof /home/arvon
    lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /root/.gvfs
        Output information may be incomplete.
    COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
    bash    24519 arvon  cwd    DIR    8,2     4096 463289 /home/arvon
    lsof    25011 arvon  cwd    DIR    8,2     4096 463289 /home/arvon
    lsof    25012 arvon  cwd    DIR    8,2     4096 463289 /home/arvon
    
  • lsof +D /usr/lib 加上+D参数,lsof会对指定目录进行递归查找,注意这个参数要比grep版本慢
    1
    2
    3
    4
    5
    6
    7
    
    arvon@Mo:~> lsof +D /usr/lib
    lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /root/.gvfs
        Output information may be incomplete.
    COMMAND   PID  USER  FD   TYPE DEVICE SIZE/OFF   NODE NAME
    bash    24519 arvon mem    REG    8,2   256324 445427 /usr/lib/locale/es_VE.utf8/LC_CTYPE
    bash    24519 arvon mem    REG    8,2       54 445420 /usr/lib/locale/om_ET/LC_NUMERIC
    bash    24519 arvon mem    REG    8,2     2454 431855 /usr/lib/locale/en_US.utf8/LC_TIME
    
  • 查看文件、设备被哪些进程占用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    # lsof /dev/tty1
    COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    bash       1770 jian    0u   CHR    4,1      0t0 1045 /dev/tty1
    bash       1770 jian    1u   CHR    4,1      0t0 1045 /dev/tty1
    bash       1770 jian    2u   CHR    4,1      0t0 1045 /dev/tty1
    bash       1770 jian  255u   CHR    4,1      0t0 1045 /dev/tty1
    startx     1845 jian    0u   CHR    4,1      0t0 1045 /dev/tty1
    startx     1845 jian    1u   CHR    4,1      0t0 1045 /dev/tty1
    ...
    
  • 监控文件系统:指定目录、挂载点,可以看到有哪些进程打开了其下的文件
    1
    2
    3
    4
    
    # lsof /data/
    COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    bash    15983 jian  cwd    DIR    8,5     4096 8252 /data/backup
    ...
    
  • 列出被指定进程名打开的文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    # lsof -c ssh -c init
    COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
    init         1       root  txt    REG        8,1   124704  917562 /sbin/init
    init         1       root  mem    REG        8,1  1434180 1442625 /lib/i386-linux-gnu/libc-2.13.so
    init         1       root  mem    REG        8,1    30684 1442694 /lib/i386-linux-gnu/librt-2.13.so
    ...
    ssh-agent 1528 lakshmanan    1u   CHR        1,3      0t0    4369 /dev/null
    ssh-agent 1528 lakshmanan    2u   CHR        1,3      0t0    4369 /dev/null
    ssh-agent 1528 lakshmanan    3u  unix 0xdf70e240      0t0   10464 /tmp/ssh-sUymKXxw1495/agent.1495
    
  • 监控进程:指定进程号,可以查看该进程打开的文件:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    # lsof -p 2064
    COMMAND  PID USER   FD   TYPE     DEVICE SIZE/OFF    NODE NAME
    firefox 2064 jian  cwd    DIR        8,6     4096 1571780 /home/jian
    firefox 2064 jian  rtd    DIR        8,6     4096       2 /
    firefox 2064 jian  txt    REG        8,6    44224 1985670 /usr/lib/firefox-12.0/firefox
    firefox 2064 jian  mem    REG        8,6 14707012  925361 /usr/share/fonts/chinese/msyhbd.ttf
    firefox 2064 jian  mem    REG        8,6 15067744  925362 /usr/share/fonts/chinese/msyh.ttf
    firefox 2064 jian  mem    REG        8,6 16791251 1701681 /usr/share/fonts/wenquanyi/wqy-zenhei.ttc
    firefox 2064 jian  mem    REG       0,16 67108904   10203 /dev/shm/pulse-shm-3021850167
    ...
    
  • 当你想要杀掉某个用户所有打开的文件、设备,你可以这样:
    1
    
    kill -9 `lsof -t -u lakshmanan`
    

监控网络

  • 监控网络:查看指定端口有哪些进程在使用(lsof -i 列出所有的打开的网络连接):
    1
    2
    3
    4
    5
    
    # lsof -i:22
    COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    sshd    1569 root    3u  IPv4  10303      0t0  TCP *:ssh (LISTEN)
    sshd    1569 root    4u  IPv6  10305      0t0  TCP *:ssh (LISTEN)
    ...
    
  • 监控网络:列出被某个进程打开所有的网络文件:
    1
    2
    
    lsof -i -a -p 234
    #lsof -i -a -c ssh
    
  • 监控网络:列出所有 tcp、udp 连接:
    1
    2
    
    lsof -i tcp;
    lsof -i udp;
    
  • 列出所有NFS文件
    1
    
    lsof -N -u lakshmanan -a   
    
  • 查看指定网口有哪些进程在使用
    1
    2
    3
    4
    5
    6
    
    # lsof -i@192.168.1.91
    COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    skype      1909 jian   54u  IPv4   9116      0t0  TCP 192.168.1.91:40640->64.4.23.153:40047 (ESTABLISHED)
    pidgin     1973 jian    7u  IPv4   6599      0t0  TCP 192.168.1.91:59311->hx-in-f125.1e100.net:https   (ESTABLISHED)
    pidgin     1973 jian   13u  IPv4   9260      0t0  TCP 192.168.1.91:54447->by2msg3010511.phx.gbl:msnp   (ESTABLISHED)
    ...
    

监控用户

  • 查看指定用戶打开的文件(lsof -u ^lakshmanan 可以排除某用户):
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    # lsof -u messagebus
    COMMAND    PID       USER   FD   TYPE     DEVICE SIZE/OFF    NODE NAME
    dbus-daem 1805 messagebus  cwd    DIR        8,6     4096       2 /
    dbus-daem 1805 messagebus  rtd    DIR        8,6     4096       2 /
    dbus-daem 1805 messagebus  txt    REG        8,6  1235361 1834948 /usr/bin/dbus-daemon
    dbus-daem 1805 messagebus  mem    REG        8,6   210473 1700647 /lib/libnss_files-2.15.so
    dbus-daem 1805 messagebus  mem    REG        8,6   190145 1700642 /lib/libnss_nis-2.15.so
    dbus-daem 1805 messagebus  mem    REG        8,6   490366 1700636 /lib/libnsl-2.15.so
    ...
    
  • 查看指定程序打开的文件:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    # lsof -c firefox
    COMMAND  PID USER   FD   TYPE     DEVICE SIZE/OFF    NODE NAME
    firefox 2064 jian  cwd    DIR        8,6     4096 1571780 /home/jian
    firefox 2064 jian  rtd    DIR        8,6     4096       2 /
    firefox 2064 jian  txt    REG        8,6    44224 1985670 /usr/lib/firefox-12.0/firefox
    firefox 2064 jian  mem    REG        8,6 14707012  925361 /usr/share/fonts/chinese/msyhbd.ttf
    firefox 2064 jian  mem    REG        8,6 15067744  925362 /usr/share/fonts/chinese/msyh.ttf
    firefox 2064 jian  mem    REG        8,6 16791251 1701681 /usr/share/fonts/wenquanyi/wqy-zenhei.ttc
    ...
    

技巧

  • 只有多个查询条件都满足, 用 “-a” 参数,默认是 -o 。
    1
    2
    3
    4
    5
    6
    7
    
    # lsof -a -c bash -u root
    COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
    bash    1986 root  cwd    DIR    8,6     4096 1701593 /root/lab
    bash    1986 root  rtd    DIR    8,6     4096       2 /
    bash    1986 root  txt    REG    8,6  1994157 1700632 /bin/bash
    bash    1986 root  mem    REG    8,6  9690800  405214 /usr/lib/locale/locale-archive
    bash    1986 root  mem    REG    8,6   210473 1700647 /lib/libnss_files-2.15.so
    
  • 关于磁盘空间告警 df -h --max=1 与 du -hx --max=1 显示不一致的问题

    最常见的的还是下面这种情况: lsof|grep -i delete 看看被删除的文件:有些删了文件,但是进程没 reload,那些空间还是占用的,你可以理解为类似 windows 下的进程句柄没释放的概念吧~ 只是 windows 下如果有文件被进程使用,你一般是删不掉的,而 linux 虽然不做删除限制,但却要等到进程使用完文件才能完全释放,以防止进程奔溃, 这是操作系统对资源的管理差异吧~ 例如 nginx 会有很多临时文件占用了 /tmp 目录,删掉后,依然占用着空间, 此时你可以: pkill -9 nginx && /etc/init.d/nginx restart

参考

使用lsof查找打开的文件 实用系统工具lsof


以上