日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux 命令之 lsof -- 列出当前系统已打开的文件列表

發布時間:2023/12/3 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 命令之 lsof -- 列出当前系统已打开的文件列表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 命令介紹
  • 常用選項
  • 字段說明
  • 文件類型
  • 文件描述符
  • 文件狀態模式
  • 鎖模式
  • 參考示例
    • (一)查看打開指定文件的所有進程
    • (二)列出由某個 PID 對應的進程打開的所有文件
    • (三)查看指定名稱的進程所打開的文件列表
    • (四)列出除了某個用戶以外的被打開的文件列表
    • (五)列出除了某個進程之外,其它進程打開的文件列表
    • (六)列出所有的網絡連接
    • (七)列出所有的 TCP 網絡連接
    • (八)列出所有的 UDP 網絡連接
    • (九)查看有哪些進程在使用指定的端口
    • (十)查看哪些進程在使用指定的 UDP 端口
    • (十一)查看哪些進程在使用指定的 TCP 端口
    • (十二)列出某個用戶所有活躍的網絡端口
    • (十三)查看指定用戶組所打開的文件列表
    • (十四)根據文件描述符的范圍查看有關的文件列表
    • (十五)哪些進程在使用 apache 的可執行文件
    • (十六)查看連接到某個遠程主機端口的進程
    • (十七)不斷查看遠程主機 ftp 連接的情況
    • (十八)遞歸查找某個目錄中所有打開的文件
    • (十九)列出某個用戶打開的所有文件
    • (二十)列出由某個用戶或某個進程打開的所有文件
    • (二十一)查看某個用戶的所有網絡連接
    • (二十二)列出所有內存映射文件
    • (二十三)列出所有加載在內存中并正在執行的進程
    • (二十四)查看使用網絡資源的進程 pid
    • (二十五)殺掉所有使用網絡的進程
    • (二十六)循環列出文件
    • (二十七)查看被打開的和網絡相關的文件
    • (二十八)統計系統打開的文件總數
    • (二十九)殺掉屬于某個用戶的打開了文件的所有進程
    • (三十)列出某個 IP 的網絡連接信息
    • (三十一)同時列出連接某主機多個端口的網絡連接文件
  • 經典場景應用
    • (一)查看指定進程打開的特定文件(查看日志文件路徑)
    • (二)查看文件的內存映射路徑(查看已刪除文件的內容)
    • (三)恢復被刪除的文件
    • (四) 日志文件刪除后磁盤空間可用空間沒有變大,怎么解決

命令介紹

lsof 是 List Opened Files 的縮寫,該命令是用于列出當前系統打開的文件的工具,也就是查看被進程打開的文件的工具,且可以用來找回或恢復被刪除的文件。

在 Linux 下“一切皆文件”,任何事物都以文件的形式存在,包括但不限于 pipes, sockets, directories, devices等。通過文件不僅僅可以訪問常規數據,還可以訪問網絡連接和硬件,例如:傳輸控制協議 (TCP) 和用戶數據報協議 (UDP) 套接字等。

lsof 是一個 Linux 下的非常實用和方便的系統級的監控、診斷工具。因為 lsof 命令需要訪問核心內存和各種文件,所以必須以 root 用戶的身份運行它才能夠充分地發揮其功能。

系統在后臺為每個應用程序分配了一個文件描述符(程序打開文件,系統都會分配一個文件描述符給該程序),該文件描述符為應用程序與基礎操作系統之間的交互提供了通用接口。因為應用程序打開文件的描述符列表提供了大量關于這個應用程序本身的信息,因此通過 lsof 工具查看這個列表,對系統監測以及排錯將是很有幫助的。

在 lsof 顯示的結果中,每行顯示一個打開的文件,若不指定條件默認顯示所有進程打開的所有文件。

常用選項

選項說明
-a指示多個選項之間為 與 的關系,必須都滿足時才顯示結果
-c<進程名>列出指定進程所打開的文件
-g顯示歸屬于 GID 的進程情況
-d<文件號>列出占用該文件號的進程,文件號就是文件描述符。例如:顯示使用fd為4的進程
+d<目錄>列出指定目錄下被打開的文件
+D<目錄>遞歸列出指定目錄下被打開的文件
-n<目錄>列出使用NFS的文件
-n不解析主機名 ,不將 IP 轉換為 Host Name,缺省是不加上 -n 選項,疑問??
-i<條件>列出符合條件的且與網絡相關的進程。(4、6、協議、:端口、 @ip )不加條件默認列出所有的網絡連接。
-p<進程號>列出指定進程號所打開的文件
-P不解析端口號
-N列出所有NFS(網絡文件系統)文件
-u<用戶名>列出指定用戶打開的文件, 該選項可以指定用戶名 或 user ID,可以通過逗號分隔多個用戶名稱或 user ID,也可以通過符號 ^ 對條件取反
-U列出所有UNIX域Socket文件
-t只輸出 PID
-h顯示幫助信息
-v顯示版本信息

字段說明

字段名稱說明
COMMAND進程的名稱,默認以 9 個字符長度顯示的命令名稱??墒褂?+c 參數指定顯示的寬度,若 +c 后跟的參數為零,則顯示命令的全名。這個 +c 參數好像無效
PID進程標識符
PPID父進程標識符,父進程的IP號,默認不顯示,當使用 -R 參數可打開。
USER進程所有者,命令的執行 UID 或系統中登陸的用戶名稱。默認顯示為用戶名,當使用 -l 參數時,可顯示 UID。
PGID進程所屬組標識符,進程組的ID 編號,默認也不會顯示,當使用 -g 參數時可打開。
FDFile Descriptor Number,文件描述符,應用程序通過文件描述符識別文件,例如:cwd、txt 等
TYPE文件類型,例如: DIR、REG 等
DEVICE指定磁盤的名稱,以逗號分隔設備編號,使用character special、block special表示的設備號
SIZE文件的大小,如果不能用大小表示的,會留空。使用-s參數控制。
NODE索引節點(文件在磁盤上的標識),本地文件的node碼,或者協議,如TCP等
NAME打開文件的確切名稱,掛載點和文件的全路徑(鏈接會被解析為實際路徑),或者連接雙方的地址和端口、狀態等

文件類型

英文標識說明
REG普通文件
DIR表示目錄
CHR表示字符類型
BLK塊設備類型
UNIXUNIX 域套接字,UNIX Domain Sockets
FIFO先進先出 (FIFO) 隊列
IPv4/IPv6網際協議 (IP) 套接字,IPv4/IPv6 套接字
LINK鏈接文件

文件描述符

描述符說明
cwdCurrent Work Director 的縮寫,應用程序的當前工作目錄,這是該應用程序啟動的目錄,除非它本身對這個目錄進行更改
txt該類型的文件是程序代碼,表示程序的可執行文件
lnnlibrary references (AIX)
erFD information error (see NAME column)
jldjail directory (FreeBSD)
ltxshared library text (code and data)
mxxhex memory-mapped type number xx
m86DOS Merge mapped file
memmemory-mapped file,表示內存映射文件
mmapmemory-mapped device
pdparent directory
rtdroot directory,表示根目錄
trkernel trace file (OpenBSD)
v86VP/ix mapped file
0表示標準輸出
1表示標準輸入
2表示標準錯誤

文件狀態模式

一般在標準輸出、標準錯誤、標準輸入后還跟著文件狀態模式。

文件狀態模式說明
u表示該文件被打開并處于讀取/寫入模式,例如:10u,10 是打開該文件時返回的一個整數,表示文件號是10,u 表示該文件被打開且處于讀取/寫入模式
r表示該文件被打開并處于只讀模式
w表示該文件被打開并處于只寫模式
space表示該文件的狀態模式為 unknow,且沒有鎖定
-表示該文件的狀態模式為 unknow,且被鎖定

鎖模式

在文件狀態模式后面,還跟著相關的鎖:

鎖模式說明
Nfor a Solaris NFS lock of unknown type
rfor read lock on part of the file
Rfor a read lock on the entire file
wfor a write lock on part of the file(文件的部分寫鎖)
Wfor a write lock on the entire file(整個文件的寫鎖)。表示該應用程序擁有對整個文件的寫鎖(表示該進程擁有對文件寫操作的鎖),該文件描述符用于確保每次只能打開一個應用程序實例。初始打開每個應用程序時,都具有三個文件描述符,從 0 到 2,分別表示標準輸入、標準輸出和標準錯誤。所以大多數應用程序所打開的文件的 FD 都是從 3 開始。
ufor a read and write lock of any length
Ufor a lock of unknown type
xfor an SCO OpenServer Xenix lock on part of the file
Xfor an SCO OpenServer Xenix lock on the entire file
spaceif there is no lock。表示該文件的狀態模式為 unknow,且沒有鎖定。
-表示該文件的狀態模式為 unknow,且被鎖定。

參考示例

(一)查看打開指定文件的所有進程

  • 查看哪些進程正在使用文件 /var/log/mysqld.log:
  • [root@htlwk0001host ~]# lsof /var/log/mysqld.log COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 1064381 mysql 1w REG 253,1 3240699 935706 /var/log/mysqld.log mysqld 1064381 mysql 2w REG 253,1 3240699 935706 /var/log/mysqld.log
  • 哪些進程在占用文件 /etc/passwd:
  • [root@htlwk0001host ~]# lsof /etc/passwd
  • 哪些進程在占用 hda6:
  • [root@htlwk0001host ~]# lsof /dev/hda6
  • 哪些進程在占用光驅:
  • [root@htlwk0001host ~]# lsof /dev/cdrom

    (二)列出由某個 PID 對應的進程打開的所有文件

    查看 PID 為 1064381 的進程所打開的全部文件列表:

    [root@htlwk0001host ~]# lsof -p 1064381 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 1064381 mysql cwd DIR 253,1 4096 636744 /var/lib/mysql mysqld 1064381 mysql rtd DIR 253,1 244 128 / mysqld 1064381 mysql txt REG 253,1 251816000 51228705 /usr/sbin/mysqld mysqld 1064381 mysql mem REG 253,1 553480 50342901 /usr/lib64/libpcre2-8.so.0.7.1 mysqld 1064381 mysql mem REG 253,1 304848 50342907 /usr/lib64/libselinux.so.1

    (三)查看指定名稱的進程所打開的文件列表

    查看進程 mysqld 所打開的全部文件列表:

    [root@htlwk0001host ~]# lsof -c mysqld COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 1064381 mysql cwd DIR 253,1 4096 636744 /var/lib/mysql mysqld 1064381 mysql rtd DIR 253,1 244 128 / mysqld 1064381 mysql txt REG 253,1 251816000 51228705 /usr/sbin/mysqld mysqld 1064381 mysql mem REG 253,1 553480 50342901 /usr/lib64/libpcre2-8.so.0.7.1 mysqld 1064381 mysql mem REG 253,1 304848 50342907 /usr/lib64/libselinux.so.1 mysqld 1064381 mysql mem REG 253,1 33224 50343274 /usr/lib64/libuuid.so.1.3.0

    -c 選項限定只列出以 mysqld 開頭的進程打開的文件:

    你同樣可以制定多個 -c 參數:

    [root@htlwk0001host ~]# lsof -c apache -c python

    這會列出所有由 apache 和 python 打開的文件。

    (四)列出除了某個用戶以外的被打開的文件列表

    [root@htlwk0001host ~]# lsof -u ^root COMMAND PID TID TASKCMD USER FD TYPE DEVICE SIZE/OFF NODE NAME polkitd 715 polkitd cwd DIR 253,1 244 128 / polkitd 715 polkitd rtd DIR 253,1 244 128 /

    說明:^ 符號,表示 取反 的意思。

    (五)列出除了某個進程之外,其它進程打開的文件列表

    [root@htlwk0001host ~]# lsof -p ^1234

    (六)列出所有的網絡連接

    列出所有打開了網絡套接字(TCP和UDP)的進程:

    [root@htlwk0001host ~]# lsof -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME chronyd 743 chrony 5u IPv4 20334 0t0 UDP localhost:323 chronyd 743 chrony 6u IPv6 20335 0t0 UDP localhost:323 NetworkMa 901 root 24u IPv4 22817 0t0 UDP htlwk0001host:bootpc->_gateway:bootps systemd-r 955 systemd-resolve 12u IPv4 23063 0t0 UDP *:hostmon systemd-r 955 systemd-resolve 13u IPv4 23064 0t0 TCP *:hostmon (LISTEN)

    (七)列出所有的 TCP 網絡連接

    [root@htlwk0001host ~]# lsof -i tcp COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd-r 955 systemd-resolve 13u IPv4 23064 0t0 TCP *:hostmon (LISTEN) systemd-r 955 systemd-resolve 15u IPv6 23067 0t0 TCP *:hostmon (LISTEN) nginx 26556 root 8u IPv4 137518 0t0 TCP *:http (LISTEN) nginx 26556 root 9u IPv4 137519 0t0 TCP *:https (LISTEN) nginx 26556 root 10u IPv6 137520 0t0 TCP *:https (LISTEN) nginx 26556 root 11u IPv6 137521 0t0 TCP *:http (LISTEN) svnserve 34295 root 3u IPv4 182743 0t0 TCP *:svn (LISTEN) httpd 34871 root 4u IPv6 186113 0t0 TCP *:tproxy (LISTEN)

    tcp 選項會強制 lsof 只列出打開 TCP sockets 的進程。

    (八)列出所有的 UDP 網絡連接

    [root@htlwk0001host ~]# lsof -i udp COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME chronyd 743 chrony 5u IPv4 20334 0t0 UDP localhost:323 chronyd 743 chrony 6u IPv6 20335 0t0 UDP localhost:323 NetworkMa 901 root 24u IPv4 22817 0t0 UDP htlwk0001host:bootpc->_gateway:bootps systemd-r 955 systemd-resolve 12u IPv4 23063 0t0 UDP *:hostmon systemd-r 955 systemd-resolve 14u IPv6 23066 0t0 UDP *:hostmon systemd-r 955 systemd-resolve 18u IPv4 23069 0t0 UDP 127.0.0.53:domain

    (九)查看有哪些進程在使用指定的端口

    讓 lsof 列出占用 TCP 或 UDP 的 3306 端口的進程:

    [root@htlwk0001host ~]# lsof -i:3306 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 1050299 root 72u IPv6 19427946 0t0 TCP htlwk0001host:60664->47.114.59.224:mysql (ESTABLISHED) java 1050299 root 78u IPv6 19427982 0t0 TCP htlwk0001host:60704->47.114.59.224:mysql (ESTABLISHED) java 1050299 root 79u IPv6 19427963 0t0 TCP htlwk0001host:60684->47.114.59.224:mysql (ESTABLISHED) java 1050299 root 80u IPv6 19427972 0t0 TCP htlwk0001host:60696->47.114.59.224:mysql (ESTABLISHED)

    你也可以使用 /etc/services 中制定的端口名稱來代替端口號,比如:

    [root@htlwk0001host ~]# lsof -i :smtp

    (十)查看哪些進程在使用指定的 UDP 端口

    [root@htlwk0001host ~]# lsof -i udp:55

    (十一)查看哪些進程在使用指定的 TCP 端口

    [root@htlwk0001host ~]# lsof -i tcp:55

    (十二)列出某個用戶所有活躍的網絡端口

    [root@htlwk0001host ~]# lsof -a -u test -i

    (十三)查看指定用戶組所打開的文件列表

    查找所有 PGID 為 5555 的進程打開的文件:

    [root@htlwk0001host ~]# lsof -g 5555;

    (十四)根據文件描述符的范圍查看有關的文件列表

  • 顯示使用 fd 為 2-3 的進程:
  • [root@htlwk0001host ~]# lsof -d 2-3 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1 root 2u CHR 1,3 0t0 6597 /dev/null systemd 1 root 3w CHR 1,11 0t0 6603 /dev/kmsg

    上面的命令會列出所有描述符為 2 或 3 的文件。

  • 顯示使用 fd 為 4 的進程:
  • [root@htlwk0001host ~]# lsof -d 4 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1 root 4u a_inode 0,14 0 9454 [eventpoll] systemd-j 560 root 4u unix 0xffff944b07050480 0t0 11200 /run/systemd/journal/socket type=DGRAM systemd-u 587 root 4u netlink 0t0 17814 KOBJECT_UEVENT auditd 673 root 4u unix 0xffff944b2d4e8d80 0t0 380481 type=STREAM

    上面這個命令會列出所有以描述符 4 打開的文件。

    (十五)哪些進程在使用 apache 的可執行文件

    [root@htlwk0001host ~]# lsof `which httpd` COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME httpd 34871 root txt REG 253,1 580064 53187782 /usr/sbin/httpd httpd 1048930 apache txt REG 253,1 580064 53187782 /usr/sbin/httpd httpd 1048931 apache txt REG 253,1 580064 53187782 /usr/sbin/httpd httpd 1049032 apache txt REG 253,1 580064 53187782 /usr/sbin/httpd httpd 1049033 apache txt REG 253,1 580064 53187782 /usr/sbin/httpd httpd 1049411 apache txt REG 253,1 580064 53187782 /usr/sbin/httpd

    (十六)查看連接到某個遠程主機端口的進程

  • 哪些進程打開了到 www.dpqyw.com 的UDP 端口 8088(ntp) 的連接:
  • [root@htlwk0001host ~]# lsof -i UDP@www.dpqyw.com:8088
  • 哪些進程打開了到 192.168.2.245 TCP 端口 1521 的連接:
  • [root@svr-db-test ~]# lsof -i tcp@192.168.2.245:1521 -n

    lsof -n 不將IP轉換為hostname,缺省是不加上-n參數。

    (十七)不斷查看遠程主機 ftp 連接的情況

    [root@htlwk0001host ~]# lsof -i tcp@www.dpqyw.com:ftp -r -n ======= ======= =======

    說明:

  • -r,lsof 會永遠不斷的執行,直到收到中斷信號
  • +r,lsof 會一直執行,直到沒有檔案被顯示,缺省是 15s 刷新
  • -n 不將 IP 轉換為 hostname,缺省是不加上 -n 參數
  • (十八)遞歸查找某個目錄中所有打開的文件

    [root@htlwk0001host ~]# lsof +D /usr/lib

    加上+D 參數,lsof 會對指定目錄進行遞歸查找,注意這個參數要比 grep 版本慢:

    [root@htlwk0001host ~]# lsof | grep '/usr/lib'

    之所以慢是因為+D首先查找所有的文件,然后一次性輸出。

    (十九)列出某個用戶打開的所有文件

    [root@htlwk0001host ~]# lsof -u liaowenxiong

    -u 選項限定只列出所有被用戶 liaowenxiong 打開的文件,你可以通過逗號指定多個用戶:

    [root@htlwk0001host ~]# lsof -u liaowenxiong,liudehua

    這條命令會列出 liaowenxiong 和 liudehua 用戶打開的所有文件。

    你也可以像下面這樣使用多個 -u 做同樣的事情:

    [root@htlwk0001host ~]# lsof -u liaowenxiong -u root

    (二十)列出由某個用戶或某個進程打開的所有文件

    [root@htlwk0001host ~]# lsof -u pkrumins -c apache

    你可以組合使用多個選項,這些選項默認進行 或 關聯,也就是說上面的命令會輸出由用戶 pkrumins 或者進程 apache 打開的文件,若希望多個選項之間是 與 關聯,可用加上選項 -a。

    (二十一)查看某個用戶的所有網絡連接

    查看用戶 root 的所有網絡連接:

    [root@htlwk0001host ~]# lsof -a -u root -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME NetworkMa 901 root 24u IPv4 22817 0t0 UDP htlwk0001host:bootpc->_gateway:bootps nginx 26556 root 8u IPv4 137518 0t0 TCP *:http (LISTEN) nginx 26556 root 9u IPv4 137519 0t0 TCP *:https (LISTEN) nginx 26556 root 10u IPv6 137520 0t0 TCP *:https (LISTEN)

    使用 -a 將 -u 和 -i 選項組合可以讓 lsof 列出某個用戶的所有網絡行為。

    (二十二)列出所有內存映射文件

    [root@htlwk0001host ~]# lsof -d mem

    (二十三)列出所有加載在內存中并正在執行的進程

    [root@htlwk0001host ~]# lsof -d txt

    (二十四)查看使用網絡資源的進程 pid

    [root@htlwk0001host ~]# lsof -t -i

    -t 選項輸出進程的 PID,你可以將它和 -i 選項組合輸出使用某個端口的進程的 PID,如下:

    [root@htlwk0001host ~]# lsof -t -i:3306 1050299 1050398 1064381

    (二十五)殺掉所有使用網絡的進程

    [root@htlwk0001host ~]# kill -9 'lsof -t -i'

    (二十六)循環列出文件

    [root@htlwk0001host ~]# lsof -r 1

    -r 選項讓 lsof 可以循環列出文件直到被中斷,參數1 就是循環間隔時間是 1 秒,即循環周期是 1 秒,意思是每秒鐘重復打印一次,這個選項最好同某個范圍比較小的查詢組合使用,比如用來監測用戶的網絡活動:

    [root@htlwk0001host ~]# lsof -r 1 -u john -i -a

    (二十七)查看被打開的和網絡相關的文件

    使用 -i 選項用來查看網絡相關的文件,其參數的格式如下:

    lsof -i [46][protocol][@hostname|hostaddr][:service|port]

    說明:

  • 46 表示 IP 協議的版本
  • protocol 表示網絡協議的名稱,比如 TCP 或 UDP
  • hostname 或 hostaddr 表示主機域名或者主機 IP 地址
  • service 指 /etc/services 中的端口名稱,比如:smtp
  • port 表示端口號,可以指定一個或多個
  • -i 選項默認會同時輸出 IPv4 和 IPv6 打開的文件。

  • 只列出 IPv4 或 IPv6 打開的文件:
  • [root@htlwk0001host ~]# lsof -i 4 [root@htlwk0001host ~]# lsof -i 6
  • 列出占用一定端口范圍的所有的進程:
  • [root@htlwk0001host ~]#lsof -i TCP:1-1024

    (二十八)統計系統打開的文件總數

    [root@htlwk0001host ~]# lsof -P -n | wc -l 69360

    命令中的 -P 選項表示不解析端口號,-n 選項表示不解析主機名,這兩個選項主要的目的是為了提升 lsof 命令的執行速度。wc -l 命令則用來統計 lsof 命令輸出的行數。

    (二十九)殺掉屬于某個用戶的打開了文件的所有進程

    [root@htlwk0001host ~]# kill -9 `lsof -t -u nick` [root@htlwk0001host ~]# kill -9 $(lsof -t -u nick)

    (三十)列出某個 IP 的網絡連接信息

    [root@htlwk0001host ~]# lsof -i @47.114.59.256 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 1050299 root 72u IPv6 19473546 0t0 TCP htlwk0001host:36448->47.114.59.224:mysql (ESTABLISHED) java 1050299 root 78u IPv6 19472650 0t0 TCP htlwk0001host:36488->47.114.59.224:mysql (ESTABLISHED) java 1050299 root 79u IPv6 19473549 0t0 TCP htlwk0001host:36450->47.114.59.224:mysql (ESTABLISHED)

    (三十一)同時列出連接某主機多個端口的網絡連接文件

    列出目前連接主機 hadoop 的端口為:20,21,22,25,53,80 的所有文件信息,且每隔3秒不斷的執行 lsof 指令:

    [root@htlwk0001host ~]# lsof -i @hadoop:20,21,22,25,53,80 -r 3

    經典場景應用

    (一)查看指定進程打開的特定文件(查看日志文件路徑)

    場景描述:

    同事今天請假了,但負責的 webserver 服務出現了問題,老板讓你看一下 webserver 服務的日志,但你不知道 webserver 服務的日志文件路徑,配置文件太復雜你不太懂,這時你可以執行以下命令查看日志文件路徑。

    [devl@xungen ~]$ lsof -c webserver | grep -e 'log$' webserver 10124 devl 4u REG 253,1 8814787 109523 /home/devl/application/webserver/log/webserver.00.log

    (二)查看文件的內存映射路徑(查看已刪除文件的內容)

    場景描述:

    新來的同事誤刪除了 webserver 服務的日志文件,現在線上環境出現問題,需要查看 webserver 的日志,老板讓緊急處理一下,這時你只能通過日志文件的內存映射路徑來查看日志內容,那么怎么獲取文件的內存映射路徑呢?你要記住內存映射路徑的固定格式:/proc/進程ID/fd/句柄。接著你要知道 webserver 進程 ID 和日志文件的句柄,那么這時我們就可以使用命令 lsof,來查看進程ID和文件句柄了。

    注意:文件句柄又叫文件描述符又叫文件號

    [devl@xungen ~]$ lsof -c webserver | grep -e 'log$' webserver 10124 devl 4u REG 253,1 8814787 109523 /home/devl/application/webserver/log/webserver.00.log

    以上的執行結果顯示 webserver 服務的進程 ID 為 10124,日志文件句柄為 4u(即 4 號句柄),所以 /proc/10124/fd/4 就是日志文件(webserver.00.log)在 webserver 進程中的內存映射路徑,這時你用 tail 命令就可查看日志文件了。

    [devl@xungen ~]$ tail -f /proc/10124/fd/4 [20190602 09:51:04|INF] start route ping process success [20190602 09:51:04|INF] ping host[127.0.0.1:8888][3951] success [20190602 09:51:09|INF] check session success [20190602 09:51:09|INF] start route ping process success [20190602 09:51:09|INF] ping host[127.0.0.1:8888][3596] success [20190602 09:51:14|INF] start route ping process success [20190602 09:51:14|INF] ping host[127.0.0.1:8888][3390] success [20190602 09:51:19|INF] start route ping process success [20190602 09:51:19|INF] ping host[127.0.0.1:8888][3383] success [20190602 09:51:19|INF] check session success

    擴展知識:

    當進程打開了某個文件時,只要該進程保持打開該文件,即使將其刪除,它依然存在于磁盤中。這意味著,進程并不知道文件已經被刪除,它仍然可以向打開該文件時提供給它的文件描述符進行讀取和寫入。除了該進程之外,這個文件是不可見的,因為已經刪除了其相應的目錄索引節點。 在 /proc 目錄下存儲著反映內核和進程樹的各種文件。/proc 目錄掛載的是在內存中所映射的一塊區域,所以這些文件和目錄并不存在于磁盤中,因此當我們對這些文件進行讀取和寫入時,實際上是從內存中獲取相關信息。大多數與 lsof 相關的信息都存儲于以進程 ID 命名的目錄中,例如: /proc/1234 中存儲的是 PID 為 1234 的進程的信息。每個進程目錄中存儲著各種文件,它們可以使得應用程序簡單地了解進程的內存空間、文件描述符列表、指向磁盤上的文件的符號鏈接和其他系統信息。

    (三)恢復被刪除的文件

    當系統中的某個文件被意外地刪除了,只要這個時候系統中還有進程正在訪問該文件,那么我們就可以通過 lsof 從 /proc 目錄下恢復該文件的內容。 假如,由于誤操作將 /var/log/messages 文件刪除掉了,那么這時要將 /var/log/messages 文件恢復的方法如下:

    首先使用 lsof 來查看當前是否有進程打開 /var/logmessages 文件,如下:

    [root@htlwk0001host ~]# lsof |grep /var/log/messages syslogd 1283 root 2w REG 3,3 5381017 1773647 /var/log/messages (deleted)

    從上面的信息可以看到進程 syslogd(PID=1283)打開文件的文件描述符為 2w。同時還可以看到 /var/log/messages 已經標記被刪除了。因此我們可以在 /proc/1283/fd/2 中查看相應的信息,如下:

    [root@htlwk0001host ~]# head -n 10 /proc/1283/fd/2 Aug 4 13:50:15 holmes86 syslogd 1.4.1: restart. Aug 4 13:50:15 holmes86 kernel: klogd 1.4.1, log source = /proc/kmsg started. Aug 4 13:50:15 holmes86 kernel: Linux version 2.6.22.1-8 (root@everestbuilder.linux-ren.org) (gcc version 4.2.0) 1 SMP Wed Jul 18 11:18:32 EDT 2007 Aug 4 13:50:15 holmes86 kernel: BIOS-provided physical RAM map: Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 0000000000000000 - 000000000009f000 (usable) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 000000000009f000 - 00000000000a0000 (reserved) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 0000000000100000 - 000000001f7d3800 (usable) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 000000001f7d3800 - 0000000020000000 (reserved) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 00000000e0000000 - 00000000f0007000 (reserved) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 00000000f0008000 - 00000000f000c000 (reserved)

    如果可以通過文件描述符查看相應的數據,那么就可以使用 I/O 重定向將其復制到文件中,命令語句如下:

    [root@htlwk0001host ~]# cat /proc/1283/fd/2 > /var/log/messages

    或者

    [root@htlwk0001host ~]# sh -c 'cat /proc/1283/fd/2 > /var/log/messages'

    然后修復文件的權限屬性并重啟 rsyslog 服務:

    [root@htlwk0001host ~]# chown messages:adm /var/log/messages [root@htlwk0001host ~]# systemctl restart rsyslog.service

    這樣就完成了 /var/log/messages 文件的恢復工作。對于許多應用程序,尤其是日志文件和數據庫,這種恢復刪除文件的方法非常有用。

    (四) 日志文件刪除后磁盤空間可用空間沒有變大,怎么解決

    發現文件系統 /tmp 目錄下空間居然用滿了,但用 du 命令統計 /tmp 目錄中所有文件的大小,發現并沒有大文件,怎么回事呢?出現這樣的情況,很有可能是被刪除的大文件依舊有其它程序在使用,所以依舊占用著磁盤空間,只是我們正常的方式無法查看到此文件,換句話說就是文件沒有被徹底刪除,這時候我們可以使用命令 lsof 求證下 。

    步驟 1:查看系統磁盤的使用情況

    [root@htlwk0001host ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 8.6G 1.5G 6.7G 18% / /dev/sda10 784G 325G 420G 44% /u01 /dev/sda5 8.7G 7.9G 407M 96% /tmp /dev/sda2 15G 2.8G 11G 21% /usr /dev/sda1 122M 12M 104M 10% /boot tmpfs 7.9G 4.0K 7.9G 1% /dev/shm

    如上所示,/tmp 可用空剩下 407M。

    步驟 2:使用命令 lsof 查看正在被進程使用的與 /tmp 相關的文件

    [root@htlwk0001host ~]# sudo lsof | grep /tmp sleep 18833 peien.htg 1w REG 8,5 8321143673 54 /tmp/netstat.log (deleted) netstat_2 13571 peien.htg 1w REG 8,5 8321143673 54 /tmp/netstat.log (deleted) tcprstat 18823 root 2w REG 8,5 43632 49 /tmp/myrt.daemon.log sh 18822 mysql 2w REG 8,5 43632 49 /tmp/myrt.daemon.log sh 18822 mysql 1w REG 8,5 43632 49 /tmp/myrt.daemon.log myrt.pl 26045 mysql 2w REG 8,5 43632 49 /tmp/myrt.daemon.log myrt.pl 26045 mysql 1w REG 8,5 43632 49 /tmp/myrt.daemon.log check_age 25298 mysql 2w REG 8,5 22049 33 /tmp/check_agent.log check_age 25298 mysql 1w REG 8,5 22049 33 /tmp/check_agent.log mysqld 3784 mysql 6u REG 8,5 15156 13 /tmp/ibH3IFN9 (deleted)

    如上所示列表中的第二行,文件大小7個多G,文件標記已刪,但是依舊被進程“netstat_2”占用,該進程的 PID=13571。

    步驟 3: 我們可以使用命令 ps 查看進程更為詳細的信息

    [root@htlwk0001host ~]# ps -ef | grep 13571 51717 13571 1 0 2011 ? 00:15:00 /bin/bash /tmp/netstat_20110829.sh 51717 21456 13571 0 09:40 ? 00:00:00 sleep 10 zhuxu 21458 17014 0 09:40 pts/0 00:00:00 grep 13571

    步驟 4:接著我們將此進程 kill 掉

    [root@htlwk0001host ~]# sudo kill -9 13571

    步驟 5:然后我們再看看那個已刪的文件是否被進程占用著

    [root@htlwk0001host ~]# sudo lsof | grep /tmp tcprstat 22084 root 2w REG 8,5 49339 49 /tmp/myrt.daemon.log sh 22083 mysql 2w REG 8,5 49339 49 /tmp/myrt.daemon.log sh 22083 mysql 1w REG 8,5 49339 49 /tmp/myrt.daemon.log myrt.pl 26045 mysql 2w REG 8,5 49339 49 /tmp/myrt.daemon.log myrt.pl 26045 mysql 1w REG 8,5 49339 49 /tmp/myrt.daemon.log check_age 25298 mysql 2w REG 8,5 24583 33 /tmp/check_agent.log check_age 25298 mysql 1w REG 8,5 24583 33 /tmp/check_agent.log mysqld 3784 mysql 6u REG 8,5 15156 13 /tmp/ibH3IFN9 (deleted) su 17013 root cwd DIR 8,5 4096 2 /tmp sort 22090 zhuxu cwd DIR 8,5 4096 2 /tmp

    如上所示結果,看不到那個已刪的大文件了。

    步驟 6:我們再看看系統磁盤分區的使用情況,確認下 /tmp 的使用空間是否增加了

    [root@htlwk0001host ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 8.6G 1.5G 6.7G 18% / /dev/sda10 784G 325G 420G 44% /u01 /dev/sda5 8.7G 56M 8.2G 1% /tmp /dev/sda2 15G 2.8G 11G 21% /usr /dev/sda1 122M 12M 104M 10% /boot tmpfs 7.9G 4.0K 7.9G 1% /dev/shm

    如上所示,目錄 /tmp 的可用空間變成 8.2G 了。

    總結

    以上是生活随笔為你收集整理的Linux 命令之 lsof -- 列出当前系统已打开的文件列表的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。