In some cases useful info about processes that use……
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
解決方法:
1,比較簡單的,重啓一下就可以了。
2,
在釋放該設備之前,讓我們找出誰在使用它。
# fuser /media/cdrom
進程正在運行,無法彈出磁盤其實是我們的錯誤。
現在,如果您是根用戶,可以隨意終止進程:
# fuser -k /media/cdrom
用lsof列出當前正在被打開的文件
一,lsof有什麼用?
lsof可以找出被特定進程所打開的文件,目錄,套接字,設備.
例子:比如有時我們不能umount掉一個分區時,我們會需要檢查,是哪些進程在使用當前的分區
以便找出進程後將它關閉
一個與腳本相關的例子:
我們使用ftp接收別人上傳的文件,有程序被放到crond中定時進行處理,
此時就有一個問題;我們如何得知當前被處理的文件是否上傳完了,
比如:如果上傳的是一張圖片,且正在傳輸中我們就進行了處理,則我們會得到一張殘缺不全的圖片
解決方法:用lsof對文件進行檢查,如果有進程在訪問,就表示還未上傳完成,可以先跳過當前文件
二,lsof的用法舉例
1,檢查目錄和文件
[root@localhost cdrom]# umount /mnt/cdrom
umount: /mnt/cdrom: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
在做umount設備時, device is busy是令人頭痛的提示
大家看,我使用的是fedora 10,umount會自動給出讓大家用lsof或fuser進行檢測的信息
[root@localhost cdrom]# lsof /mnt/cdrom
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 2705 root cwd DIR 8,1 8192 1 /mnt/cdrom
lsof 2756 root cwd DIR 8,1 8192 1 /mnt/cdrom
lsof 2757 root cwd DIR 8,1 8192 1 /mnt/cdrom
可以看到,有3個進程在訪問/mnt/cdrom,程序分別是 bash和lsof,
lsof給出的信息很全,還列出了進程的id及用戶
因爲我們當前就處在cdrom目錄下,所以bash也是其中打開cdrom目錄的一個進程
下面我們從目錄下退出:
[root@localhost winc]# cd
[root@localhost ~]# umount /mnt/cdrom
這個例子提醒大家:如果umount一個分區時,lsof列出的進程中有bash,
通常是有用戶登錄在此目錄下,通知用戶讓他從目錄下cd出來就可以了
還有一種情況:如果是apache在訪問當前分區怎麼辦?
象apache或其他daemon在訪問分區,很簡單,
只需要停止daemon就可以了
2,有沒有這種可能:我們用lsof看不到進程,但是在做umount時系統仍然提示 device is busy?
有這種可能,
一個例子:
[root@search root]# umount /store2
umount: /store2: device is busy
[root@search root]# lsof /store2
很奇怪,我們用lsof看不到訪問/store2的進程,但umount時系統卻告訴我們說:
device is busy
爲什麼會這樣?
是因爲有可能nfs正在使用此進程
查看/etc/exports,此目錄便位於其中
[root@search root]# cat /etc/exports
/store2 201.103.105.37(rw,sync,no_root_squash)
/store2 201.103.105.36(rw,sync,no_root_squash)
此時如何處理?
把/etc/exports中的nfs出去的目錄註釋掉,用#加在每一行前面即可
然後無需重啓 nfs,執行 exportfs -rv即可
3,根據進程id得到其打開的文件列表:
我們查看一個apache進程所打開的文件列表:
[root@www ~]# lsof -p 2759
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
httpd 2759 nobody cwd DIR 253,0 4096 2 /
httpd 2759 nobody rtd DIR 253,0 4096 2 /
httpd 2759 nobody txt REG 253,0 1885982 4622117 /usr/local/apache2/bin/httpd
httpd 2759 nobody mem REG 253,0 334391 4621269 /usr/local/apache2/lib/libaprutil-0.so.0.9.12
httpd 2759 nobody mem REG 253,0 374273 4621265 /usr/local/apache2/lib/libexpat.so.0.1.0
httpd 2759 nobody mem REG 253,0 578133 4621251 /usr/local/apache2/lib/libapr-0.so.0.9.12
httpd 2759 nobody mem REG 253,0 21546 4407507 /usr/lib64/gconv/gconv-modules.cache
httpd 2759 nobody mem REG 253,0 30070 9519340 /lib64/libcrypt-2.3.4.so
httpd 2759 nobody mem REG 253,0 18848742 4622118 /usr/local/apache2/modules/libphp5.so
......
它打開的文件很多,我不再全列出
4,列出某個終端上的用戶正在做什麼?
例如:
我們先登錄到一個終端上面:(先用tty得到當前終端)
[root@search root]# tty
/dev/pts/2
[root@search root]# cat
然後登錄到另一終端:
[root@search root]# lsof /dev/pts/2
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
cat 514 root 0u CHR 136,2 4 /dev/pts/2
cat 514 root 1u CHR 136,2 4 /dev/pts/2
cat 514 root 2u CHR 136,2 4 /dev/pts/2
bash 32551 root 0u CHR 136,2 4 /dev/pts/2
bash 32551 root 1u CHR 136,2 4 /dev/pts/2
bash 32551 root 2u CHR 136,2 4 /dev/pts/2
bash 32551 root 255u CHR 136,2 4 /dev/pts/2
5,列出所有命令名字相同的進程所打開的全部文件
例如:apache的進程名命令全部都是httpd
我們列出apache打開的所有進程時,可以使用 -c參數,
[root@search yc]# lsof -c httpd
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
httpd 15722 root cwd DIR 8,8 4096 2 /
httpd 15722 root rtd DIR 8,8 4096 2 /
httpd 15722 root txt REG 8,2 1701872 1087581 /usr/local/apache/bin/httpd
httpd 15722 root mem REG 8,8 103044 31946 /lib/ld-2.3.2.so
httpd 15722 root mem REG 8,8 23668 31955 /lib/libcrypt-2.3.2.so
httpd 15722 root mem REG 8,2 877128 69041 /usr/lib/libsablot.so.0.100.1
httpd 15722 root mem REG 8,2 442752 69039 /usr/lib/libjs.so
httpd 15722 root mem REG 8,2 130104 64938 /usr/lib/libexpat.so.0.4.0
httpd 15722 root mem REG 8,2 52616 64985 /usr/lib/libz.so.1.1.4
httpd 15722 root mem REG 8,2 136068 66295 /usr/lib/libcurl.so.2.0.2
httpd 15722 root mem REG 8,8 76552 31977 /lib/libresolv-2.3.2.so
httpd 15722 root mem REG 8,8 211948 95819 /lib/tls/libm-2.3.2.so
......
進程太多,不一一列舉
6,根據目錄,列出指定目錄下被進程打開的文件或目錄
先看兩個參數:
+d,只搜索當前目錄下被打開的文件或目錄
+D,遞歸搜索當前目錄下被打開的文件或目錄
(注意此參數會導至速度變慢)
例子:
[root@search yc]# mkdir abc
[root@search yc]# cd abc/
在另一終端執行lsof
[root@search root]# lsof +d /store2/yc/
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 32473 root cwd DIR 8,16 4096 111329281 /store2/yc/abc
下面我們再深入一層目錄
[root@search abc]# mkdir def
[root@search abc]# cd def
還是到另一終端執行lsof
[root@search root]# lsof +d /store2/yc/
[root@search root]#
看不到進程了,因爲def不再是直接在/store2/yc目錄下,而是更下一層,則此時需要+D
[root@search root]# lsof +D /store2/yc/
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 32473 root cwd DIR 8,16 4096 111345665 /store2/yc/abc/def
7,查看打開某個端口的所有進程
[root@search root]# lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
httpd 15722 root 22u IPv4 1863715557 TCP *:http (LISTEN)
httpd 28161 nobody 22u IPv4 1863715557 TCP *:http (LISTEN)
httpd 28162 nobody 22u IPv4 1863715557 TCP *:http (LISTEN)
httpd 28163 nobody 22u IPv4 1863715557 TCP *:http (LISTEN)
.......
[root@search root]# lsof -i :21
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
xinetd 9362 root 6u IPv4 -1253197382 TCP *:ftp (LISTEN)