找回密码
 注册
关于网站域名变更的通知
查看: 299|回复: 1
打印 上一主题 下一主题

Unix调试的瑞士军刀:lsof

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-3-18 13:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
3 t( b0 k. n( ]0 \
这是“你应该知道的Unix和Linux命令”系列的第三篇,在这篇文章中,我会介绍lsof这个工具,如果说netcat是进行网络诊断的瑞士军刀,那么lsof就是Unix调试的瑞士军刀。
8 O3 H* h/ ~) ^! m$ o8 Y
8 f2 @( d' z2 `; l/ SLsof是遵从Unix哲学的典范,它只做一件事情,并且做的相当完美——它可以列出某个进程打开的所有文件信息。打开的文件可能是普通的文件,目录,NFS文件,块文件,字符文件,共享库,常规管道,明明管道,符号链接,Socket流,网络Socket,UNIX域Socket,以及其它更多。因为Unix系统中几乎所有东西都是文件,你可以想象lsof该有多有用。: N0 f/ r! ^* v' ~
7 p/ y0 N% v) f# `: a/ y% p- w$ r! a
如何使用lsof?" G8 U/ I; b! a3 V

. }8 R# z- k- ]) l9 y' I这篇文章中我会尽力列举我能想到的所有lsof的用法,让我们先从最简单的开始(或许你已经知道了),然后逐渐增加复杂度:0 J; O8 r" e1 h) `3 c
+ M& L  {1 H  E+ |. k+ |5 I" T( T
列出所有打开的文件$ T, Z, B: Y( E( b; \- F+ F

( x9 l2 U( n0 D+ `& _% j# lsof: ]! |1 e4 [# w6 |7 g1 K8 ^
+ G! V9 [; A8 Z% }7 S
不带任何参数运行lsof会列出所有进程打开的所有文件。8 H% g8 C2 F; i, f" \: a

: C8 A' P  `; n& c- h2 [找出谁在使用某个文件
9 m# D# z7 k! D8 b1 J% J' e$ ]2 {7 x/ n5 X
# lsof /path/to/file, K1 `  w) K! q5 F

4 w( Q% H9 _: n7 o" v只需要执行文件的路径,lsof就会列出所有使用这个文件的进程,你也可以列出多个文件,lsof会列出所有使用这些文件的进程。
2 ~/ Y0 v7 i. {3 w( p
: N! y: Y% \/ B* H' s$ E' A: g. f你也可以一次制定多个文件:
+ E6 k6 M* @; h1 d  H1 X  Q) f: }* H! X9 W% I
# lsof /path/to/file1 /path/to/file2# r# `6 v# A0 c4 H
# @4 D& E0 }' P- I: ~
递归查找某个目录中所有打开的文件
* t9 r9 ^: E  r4 {% N
1 V9 Y8 x0 k' v, I) g  x0 \# lsof +D /usr/lib
7 x$ b. y! P7 G
% C/ v* ^0 o7 @: W/ r加上+D参数,lsof会对指定目录进行递归查找,注意这个参数要比grep版本慢:
# e& \4 h# B/ f& C5 o' s, s# V8 b9 X" D# t
# lsof | grep '/usr/lib'
+ a  ?/ w" W7 g: ~
" o+ o, W2 i0 [' x之所以慢是因为+D首先查找所有的文件,然后一次性输出。7 S" P2 D- q# Z' ~( Y

0 L) [3 R$ @! r列出某个用户打开的所有文件
( i. u4 i- K$ O( W2 ~, k/ \5 Y/ h! W" Y3 e4 N
# lsof -u pkrumins# R1 N7 N5 d. n1 T4 P% n+ L

* k, H3 @) v1 K' \4 C-u选项限定只列出所有被用户pkrumins打开的文件,你可以通过逗号指定多个用户:5 B& @- Y! H) T$ U

+ j1 q' R, w' f5 a- u# lsof -u rms,root) L* ?9 k7 ]% c$ w8 B  j

8 z6 B# p$ i7 P2 T9 X这条命令会列出所有rms和root用户打开的文件。
9 `" e" D" B1 h5 W
8 J: J& t- D( x' n& q0 S# y3 F你也可以像下面这样使用多个-u做同样的事情:
% I5 a* @- p# ^  {! m/ P  x* A: L
# lsof -u rms -u root) Z7 J7 r! D6 d, Q+ ?& {/ e# o
4 e+ c3 m2 Z) u9 L) W- r, G
查找某个程序打开的所有文件5 H* C/ f9 L# D; v: F8 ]$ W" g+ u

) `% q7 y' N" M" v) b7 \7 o9 z# lsof -c apache
0 D; F7 C# U! u2 W
. K* Q/ P% {* J' J-c选项限定只列出以apache开头的进程打开的文件:
# ~0 _, k9 }! w# C! H4 z2 s- D6 i4 h
所以你可以不用像下面这样写:- D: |1 a4 B. O9 r# R7 x4 S6 A
. Y5 u" E' X' w& z& S6 j' }
# lsof | grep foo7 W" y0 H# B: U& |

0 e! `, S) w5 u; i3 i7 Q而使用下面这个更简短的版本:
) ], R( Y4 e9 n+ P. F; {, ^7 U# P9 J2 C9 }* l1 X0 }7 A& d& n- @$ [
# lsof -c foo3 K7 L  Q9 K. }( g$ H

  l. ~3 A. b5 u% ^事实上,你可以只制定进程名称的开头:
8 b% Z+ S( |7 l4 Z' E/ ]* j  I5 c% U
# lsof -c apa
+ X) v8 ]/ y! q# U1 }: K1 P  b, s% j+ h7 f; K- a9 U+ K
这会列出所有以apa开头的进程打开的文件
" Y: W0 w. R% t7 m0 q8 t
/ B( N) L' `$ R0 s你同样可以制定多个-c参数:+ ~% `1 A" z. J3 n3 H: \
) G. e% y, ~, ]3 b
# lsof -c apache -c python
# Q4 a. R4 [  f$ J, }6 U- m
: H/ i$ b' N9 q0 N2 N( x5 w这会列出所有由apache和python打开的文件+ l0 ]3 R* Z' n$ l9 Z: T

) T! k2 g9 |, b4 L; S  k# Z/ S列出所有由某个用户或某个进程打开的文件
& O3 X! U) d: s4 s
  y% v0 M* L7 B, A* o* x; y# lsof -u pkrumins -c apache
* E. J1 R- @9 h. e+ v1 P* {
6 d, u7 I% X: ^. u你也可以组合使用多个选项,这些选项默认进行或关联,也就是说上面的命令会输入由pkrumins用户或是apache进程打开的文件。  J* Y2 d$ a. R$ [4 p

( l# Z/ K' U; h. l1 U' B列出所有由一个用户与某个进程打开的文件
, k4 l8 ^$ u* ]3 ?/ i
* k; P! D2 |! s! R# lsof -a -u pkrumins -c bash: v4 ]# @+ ]" l* a9 d+ N, f9 _

8 J9 n  p3 t/ I+ [- B/ l; m$ P( U7 [-a参数可以将多个选项的组合条件由或变为与,上面的命令会显示所有由pkrumins用户以及bash进程打开的文件。
+ T, V$ s% B- S& C0 d7 X% t
+ R3 a! O+ u0 k. b9 N& W  |( a列出除root用户外的所有用户打开的文件# {% T# `  Y, g  y
2 H( ~. w# n7 b) }0 |" r
# lsof -u ^root
$ N5 h- @/ V, Z; {. _$ Y- r8 W+ b
4 [6 H2 O2 c/ ?* t. q注意root前面的^符号,它执行取反操作,因此lsof会列出所有root用户之外的用户打开的文件。
; o9 L) Z2 X& o( y1 g- z9 o& H
7 N% I8 B. w2 N列出所有由某个PID对应的进程打开的文件
% L6 x* p/ S6 G8 E7 P! T+ L  G1 t7 d7 B* Y' J" h
# lsof -p 1
! H4 w( t7 w$ t7 M$ {' `
! Z5 f) w* Z) X$ j2 {-p选项让你可以使用进程id来过滤输出。
* }: K; S" ]2 F$ R9 Z' T0 G, g$ S8 ~( c# N. |5 \, A
记住你也可以用都好来分离多个pid。1 Y8 g6 y' l1 s- U9 j: x5 \
; `& D3 S" r7 |/ N- ]$ \5 x
# lsof -p 450,980,3331 P0 v6 ~0 E, }& N. X
# Y7 s6 s7 C" f0 \7 D
列出所有进程打开的文件除了某个pid的
/ `& J0 r2 ?  y3 d0 S* m3 k4 F8 u, V" \
# lsof -p ^16 g$ H5 T3 Z8 L; i6 q% N- D
, X6 L/ f6 I9 ]. z# q/ j
同前面的用户一样,你也可以对-p选项使用^来进行取反。! @& n% R+ r  F' u/ P  V
- X( J4 d! S) ^3 [  C9 b
列出所有网络连接
0 O5 M0 \3 p, ^! E9 [5 y8 X6 I5 J7 s  [! f6 i' s
# lsof -i% z# k3 F) [+ {; t; u

# ~+ D1 I! I; L$ N6 K% G1 Nlsof的-i选项可以列出所有打开了网络套接字(TCP和UDP)的进程。
0 E2 ^! m9 m  D9 [4 |, H' R/ V& i9 p  B2 g1 f
列出所有TCP网络连接
+ |1 x, \) j& {. ]* S0 _" I* {& ^. {3 F: ]
# lsof -i tcp
7 S. Z+ a$ g; f9 I( S5 q) a7 p
$ Q( p. T6 y9 r  [1 U也可以为-i选项加上参数,比如tcp,tcp选项会强制lsof只列出打开TCP sockets的进程。0 P, Y6 T! c; G) `

6 h8 k/ g0 Q5 \/ k/ Y列出所有UDP网络连接5 M9 a3 j! k1 ]8 j+ E3 H: Q

5 f2 D% W/ m5 h# lsof -i udp
" X8 {, Z! b7 i! ^' W3 h
% q1 {8 M& `4 ?7 l) `同样udp让lsof只列出使用UDP socket的进程。7 h, l% l9 @: Z& I
: Z9 c5 G$ ]& E7 I; [! @
找到使用某个端口的进程3 I! Q: a8 n2 R5 Z& V) ^" z2 }0 P5 ^9 J

3 \- y" r2 |0 Q# lsof -i :25
" [# o* ]1 k8 Q9 z. n
+ I5 j4 ^) B; W) n' V7 i; d:25和-i选项组合可以让lsof列出占用TCP或UDP的25端口的进程。
. A" \+ n2 z, F7 s8 T# T) r, P4 F3 k, ?! K) T
你也可以使用/etc/services中制定的端口名称来代替端口号,比如:
0 E  y& Z3 S6 f4 y6 U. t4 h6 C
" X9 o8 N7 G9 G) j' a# lsof -i :smtp
0 R  c: i2 X! r
5 x- l- K4 q: j, U/ D2 E7 Z找到使用某个udp端口号的进程
2 ^! u2 W2 Z& h% H& f9 V# F2 v' |- f/ ]
# lsof -i udp:53
; C; S8 [( V  I, ^& L% }! T
- U& |6 }, K( |* x% E) j同样的,也可以找到使用某个tcp端口的进程:
  j: o+ }$ q: ]- Q7 k0 j
( Z: p) [7 M5 w, M/ D: b# lsof -i tcp:80; D5 c9 j3 H! [" F; n

; n8 G3 q2 D; [$ ^! ?$ ^" n3 A找到某个用户的所有网络连接5 u' l5 o) s2 S9 g/ u
1 y: a! E( ^& R" i- A3 ~
# lsof -a -u hacker -i
9 `- a5 W3 s) r; `9 i( k% Q, d' {* D1 j2 i# c
使用-a将-u和-i选项组合可以让lsof列出某个用户的所有网络行为。
: q6 m$ v, J4 i5 F$ ?  j! t* m! B4 d$ [" L* w" p: l7 ^' y# C- Z! l/ c
列出所有NFS(网络文件系统)文件
. w" H- u. K7 S; Q8 H: q
7 e8 E# C! E. ]1 f# lsof -N
" Q% k5 W+ M/ ~  x* o0 s$ U3 e! J8 b% e  S
这个参数很好记,-N就对应NFS。1 W9 M( ]3 p8 R% R( p

# g2 b2 `0 a$ C' \! w列出所有UNIX域Socket文件
, p; a, i' l, g, R$ m1 E2 N
( x8 S! e3 i$ S3 Z4 Y3 G; f- E# lsof -U8 x+ X" N# `9 F2 s4 @& v. h* ^5 X
$ ?/ r- B1 z- b
这个选项也很好记,-U就对应UNIX。! m1 k; [) f5 _9 f0 }1 e

6 l8 Q/ ?- Q' M1 F! P& \列出所有对应某个组id的进程1 V: v& W( X) |5 V2 v: U3 C8 y

( g4 R0 F# @( m# O7 O- m, L. C- G2 |# lsof -g 1234
0 Y: Z: V$ R# P2 P9 K, K. [* U2 F8 h% |( p6 l6 S% Q$ I/ W. n4 H# r
进程组用来来逻辑上对进程进行分组,这个例子查找所有PGID为1234的进程打开的文件。
+ N7 m! ^( o6 q% O; t. v! r- V* [; @$ {9 U. x4 W! w& |
列出所有与某个描述符关联的文件
% v& k, Z4 B  Y# ~( J  A5 J: Y% ~- K: _6 `. R
# lsof -d 2" v% }. |3 S+ F9 y3 c

" @1 O: ~2 S+ k6 t这个命令会列出所有以描述符2打开的文件。# F1 [, U! W8 M9 A: I; B
+ b, {9 o0 O& W! K+ K
你也可以为描述符指定一个范围:2 y2 N/ D" n) z: B9 s/ A

9 p1 M8 |3 ?% x% e6 `) E) N9 W# lsof -d 0-2! w: y7 o6 T. ^

, t1 U* h( i( t# ^# s这会列出所有描述符为0,1,2的文件。
& I7 b7 `( c, q" n4 A+ d- O% Q/ M8 p
-d选项还支持其它很多特殊值,下面的命令列出所有内存映射文件:8 I( d! \( M) Z2 y9 T6 q; ]* b
! H6 v: ~( `- W5 J; I- m+ U
# lsof -d mem
& m2 P- a# U, Z, g+ U+ z3 f$ S, B. p% {
txt则列出所有加载在内存中并正在执行的进程:
7 \9 t7 L; m' H% V/ {2 \6 z
, y9 Y- {3 \1 N7 ^' G# lsof -d txt- }" x+ i, b8 Z, W

6 N/ j2 C: f$ d- J输出使用某些资源的进程pid( s$ H( R. N# O$ {- K/ R* Z" t
. w/ X/ B' h/ M) H4 ]8 E& b5 k
# lsof -t -i
# @3 X3 I% t3 Y0 _2 R* U' a; k' b
. j1 B% L: t6 @& j-t选项输出进程的PID,你可以将它和-i选项组合输出使用某个端口的进程的PID,下面的命令将会杀掉所有使用网络的进程:
; O  \, c4 h' Z! a
, w* n8 H6 w( v: y8 E  n# kill -9 `lsof -t -i`" Y( b* V# x* H% m& B
. g" o" s3 {9 y% w1 ]
循环列出文件
# p6 Y; z2 W5 \$ N# Z5 I% L* |+ n5 d' }# r) g& N3 x3 R- {3 @8 ?
# lsof -r 1
' j/ s7 C; q/ q/ i( ?  w9 t3 `5 }& q8 M$ m3 s9 y" ^$ s' b* S5 m
-r选项让lsof可以循环列出文件直到被中断,参数1的意思是每秒钟重复打印一次,这个选项最好同某个范围比较小的查询组合使用,比如用来监测网络活动:, M$ Z$ q' E8 Z; V
$ h0 ]0 k/ x; D8 e. k/ G
# lsof -r 1 -u john -i -a
  Q# P( t: A4 }+ c3 p* a8 P3 \7 A9 C; k8 F; B/ |; |8 |
如何安装lsof?0 |: O" T# R$ Z# k7 J/ f  [- n

: @! T) J& F; f' I) q许多Unix系统都内置了lsof,如果你的系统没有安装,你可以从这里直接下载源代码。
, R6 j' g; q! [6 G
+ {* V2 K, Z# [( Z! b( R5 yBSD系统有一个类似的工具可以做同样的事情,叫做fstat。- e$ V) o; X4 q4 B' z5 K# c) o
% s# S: U' \& P' Q/ N9 d4 Z* Z, }
你可以通过man lsof来了解关于lsof的完整文档,或者通过lsof -h查看。
( t9 k& {2 X# R! b: T$ H- `
6 Y. b6 q+ u1 D0 X" Y* z6 o开始体验lsof的乐趣吧!

该用户从未签到

2#
发表于 2020-3-18 18:00 | 只看该作者
Unix调试的瑞士军刀:lsof
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-25 23:06 , Processed in 0.156250 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表