Linux入門之進程管理(4)之進程與文件linux
前面使用進程相關命令管理工具都是根據進程編號或者進程名稱及其其它屬性信息來查看和處理相關進程的,可是在某些狀況下,想要查看某個文件或者某個設備被哪些進程所使用,使用ps、pgrep等命令查詢的是不夠準確的,並且有些時候並非簡單的去打開某個文本文件同樣,這樣還能夠進行搜索過濾出來。而在linux系統中,除了常見的配置文件、日誌文件等文本文件,幾乎任何對象都會被內核映射去該有的文件,好比磁盤設備、掛載點等。當要知道那些用戶經過哪些進程來在訪問或者使用此文件時,就須要經過向文件的方式去查找其來連接的進程了。 bash
linux軟件包中也提供了一些相關命令來解決:fuser lsofsocket
fuser 命令ide
fuser - identify processes using files or sockets函數
經過文件或者套接字文件來識別器對應的進程工具
選項與參數:oop
fuser [-umv] [-k [i] [signal]] file/dirspa
-u:除了進程的PID以外,同時列出該進程的擁有者;命令行
-m:後面接的那個文件名會主動的上提到該文件系統的最頂層,對於umount不成功頗有效3d
-v:能夠列出每一個文件與進程還有指令的完整相關性;
-k:找出該文件/目錄的PID,並對與其PID對應的進程發送SIGKILL信號;
-i:必須與 -k 配合,在刪除PID 以前會先詢問使用者,交互式;
-signal:例如 -l -15 指定信號代碼,不指定默認爲SIGKILL(-9)信號。
使用案例:
一、顯示信息字段介紹
#找出對當前所在目錄的進行使用的進程的PID、所屬用戶、權限
[root@localhost ~]# fuser -uv . USER PID ACCESS COMMAND /root: root 13357 ..c.. (root)bash root 14154 ..c.. (root)bash
解析:這裏當前目錄在root家目錄,有兩個PID也就是兩個進程號分別爲1335七、14154的進程在訪問此目錄,此進程所屬用戶爲root,而且進程指令爲bash。在ACCESS訪問的那一列有不少字符,下面一一介紹:
ACCESS:
c current directory. #當前所在此目錄
e executable being run. #已經運行的執行文件
f open file. f is omitted in default display mode. #被打開的文件
F open file for writing. F is omitted in default display mode.
#該文件被開啓,可是在等待迴應中
r root directory. #表明頂級目錄(root directory)
m mmap'ed file or shared library. #可能爲分享的動態函數庫
二、指定目錄或文件訪問進程列表查看
查看某個文件系統下有多少個進程正在佔用該文件,使用-m選項指定掛載點
#開啓另外一個終端bash進程來備份當前關盤鏡像
[root@localhost ~]# dd if=/dev/cdrom of=/test/mk.iso
#回到剛纔終端查看/dev/cdrom設備
[root@localhost ~]# fuser -uv /dev/cdrom USER PID ACCESS COMMAND /dev/sr0: root 14756 f.... (root)dd
說明:f表示是一個被開啓的文件,由於要讀取光盤數據,確定是會打開訪問的。
#查看/proc虛擬文件系統掛載點又多少進程在訪問
[root@localhost ~]# fuser -muv /proc/ USER PID ACCESS COMMAND /proc: root kernel mount (root)/proc root 1 f.... (root)systemd root 2 ...e. (root)kthreadd root 3 ...e. (root)ksoftirqd/0 root 5 ...e. (root)kworker/0:0H root 7 ...e. (root)migration/0 root 8 ...e. (root)rcu_bh root 9 ...e. (root)rcuob/0
三、查看指定目錄訪問用戶及進程
查看全部使用到/home這個文件系統的進程
#使用另外一個終端用hadoop並切換到用戶家目錄
[root@localhost ~]# su - hadoop [hadoop@localhost ~]$ whoami hadoop [hadoop@localhost ~]$ pwd /home/hadoop
#查看當前所在的bash進程
[hadoop@localhost ~]$ echo $$ 14803
#使用fuser 命令查詢出/home下訪問的進程指令及用戶和PID
[hadoop@localhost ~]$ fuser -muv .. USER PID ACCESS COMMAND /home: root kernel mount (root)/ hadoop 14803 .rce. (hadoop)bash
解析:這裏顯示了當前hadoop開啓的PID爲14803的bash進程,下面用pidof來確認。
#使用pidof確認當前所在會話進程
[hadoop@localhost ~]$ pidof -s bash 14803
說明:這裏的進程的發起者爲hadoop和其訪問目錄,/home自己爲/目錄的目錄,rce則表示此當前已經在此目錄中,而且正在打開使用中,由於hadoop在/home/hadoop下,固然已經進入了,且爲頂級目錄。
四、掛載點目錄的強制卸載
當有時候由於有內存中大量的數據還沒有寫入到文件系統的掛載點中,可是又想要卸載此掛載點,這時就能夠用到-k和-m選項來指導掛載點並強制中止掛載點的使用。
#查詢新建的/dev/sda3分區的掛載點爲/test目錄
[root@localhost ~]# findmnt /dev/sda3 TARGET SOURCE FSTYPE OPTIONS /test /dev/sda3 ext4 rw,relatime,seclabel,data=ordered
#下面對此目錄進行大連讀寫操做
[root@localhost ~]# tar -jcf /test/iso.bak /mnt/Packages/* &
#肯定此進程仍在後臺運行
[root@localhost ~]# jobs [1]+ Running tar -jcf /test/iso.bak /mnt/Packages/* &
#使用umount卸載/test掛載點
[root@localhost ~]# umount /test/ umount: /test: target is busy. (In some cases useful info about processes that use the device is found by lsof(8) or fuser(1))
說明:這裏閒了了target is busy表示此掛載點目錄正在被使用中,因此沒法卸載,在以往可使用pkill、pgrep等命令來查看tar相關進程並進行kill -9來強制殺掉此進程,可是若是使用pkill或者pgrep的-f選項來完整過濾命令行是很難精確匹配的,若是在多個終端上都有此訪問,可能會誤殺。
#所以使用fuser直接找到對應的文件目錄的進程PID
[root@localhost ~]# fuser -muv /test/ USER PID ACCESS COMMAND /test: root kernel mount (root)/test root 14877 F.... (root)bzip2
說明:這裏顯示了F說明此目錄並每人進入範圍而是後臺對其操做。而且顯示的肯定命令竟然顯示不是tar命令,而是bzip2命令,這就更好解釋了,由於tar -j命令就是調用bzip2命令進行對歸檔文件的壓縮。對此能夠判斷經過這裏能夠看到最直接的命令調用。
#使用-k默認發送-9信號,-m將/test目錄排隊到文件系統映射的最前面,這樣殺死對目錄有訪問有關的全部進程都會殺死。
[root@localhost ~]# fuser -km /test /test: 14877
#再次查看/test目錄下的進程,只有最基本的系統內核的文件系統了
[root@localhost ~]# fuser -muv /test/ USER PID ACCESS COMMAND /test: root kernel mount (root)/test
#下面直接卸載,沒有提示錯誤或警告
[root@localhost ~]# umount /test
#再次查看當前掛載點中,經過與運算符判斷輸出,已經被卸載掉了
[root@localhost ~]# mount | grep '\</test/\>' && echo 'mountpoint such' || echo 'mountpoint no such' mountpoint no such
lsof 命令
lsof - list open files
與fuser查看文件的相關進程信息相反,此命令是經過進程來列出對應進程所在使用的文件。
選項與參數:
lsof [-aUn] [+d]
-a:多項數據須要同時成立才顯示出結果,相似find中-a的做用;
-U:僅列出unix like 相關的 socket 文件類型;
-uuname:列出指定進程的生效者所開啓的文件;
+ddirpath:找出指定目錄下已經被開啓的文件;
使用案例:
#列出當前系統上面全部被開啓的文件
[root@localhost ~]# lsof
說明:這裏的信息與ps直接列出的信息有些相識,只是CMMADN列爲直接調用的命令名,而
NAME則表示了被開啓的文件的完整路徑。DEVICE列還顯示了對應的文件所在文件系統的主設備號和此設備號。USER顯示了使用的用戶,TYPE顯示了此文件的類型。還有NODE此列表示文件對應的indoe編號。
#累出關於root的全部進程開啓的socket文件
[root@localhost ~]# lsof -u root -a -U
解析:由於套接字爲進程間通訊時臨時產生,全部爲內存中的臨時文件,這裏的DEVICE表示了每一個套接字文件對應的其惟一的標識符號。
#列出全部系統上列出的被啓動的周邊裝載
[root@localhost ~]# lsof +d /dev
#配合grep過濾出只屬於root用戶咋在bash進程所開啓的文件
[root@localhost ~]# lsof -u root | grep '\<bash\>'