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

Unix调试的瑞士军刀:lsof

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

; b$ f) ?, X$ D2 F0 p7 ?) u: ]这是“你应该知道的Unix和Linux命令”系列的第三篇,在这篇文章中,我会介绍lsof这个工具,如果说netcat是进行网络诊断的瑞士军刀,那么lsof就是Unix调试的瑞士军刀。
; @" B) C. V  \2 [, S' M8 U; H
4 n3 u7 y8 P9 K; `1 w1 OLsof是遵从Unix哲学的典范,它只做一件事情,并且做的相当完美——它可以列出某个进程打开的所有文件信息。打开的文件可能是普通的文件,目录,NFS文件,块文件,字符文件,共享库,常规管道,明明管道,符号链接,Socket流,网络Socket,UNIX域Socket,以及其它更多。因为Unix系统中几乎所有东西都是文件,你可以想象lsof该有多有用。
" T4 o3 c$ O& k' n
- S/ d. ^9 k2 U) l% A$ [$ G如何使用lsof?
7 |$ y. V$ `6 m8 ^% \* P! {* p( }  y' N/ {; F
这篇文章中我会尽力列举我能想到的所有lsof的用法,让我们先从最简单的开始(或许你已经知道了),然后逐渐增加复杂度:
9 g. q, L% x9 u& i' \1 |7 e9 h) X/ w. g/ m
列出所有打开的文件4 O# w) D$ S8 h3 Z" q  h4 [  K' y# v

& X( u! R& z$ J3 |6 V) G% W# lsof
: W, a. J; \, R1 K8 ?% |7 G5 ^6 r, B6 `' }
不带任何参数运行lsof会列出所有进程打开的所有文件。0 N( h0 D4 \/ ^* A

- l* K9 {$ E* S& ?( p找出谁在使用某个文件
, f7 X  }, |: t. `. r# h( d  ^0 g# n, I* P- P6 B4 X5 }
# lsof /path/to/file/ ]% w, O: Y& ^4 z& \9 O
+ D7 `8 N- k! n
只需要执行文件的路径,lsof就会列出所有使用这个文件的进程,你也可以列出多个文件,lsof会列出所有使用这些文件的进程。
8 E' o  p, X* T$ |9 L; R9 j; W! Y: G. o: b
你也可以一次制定多个文件:0 h9 f+ r- O) N- p

7 d/ p% G0 Z' W( l& V* P# lsof /path/to/file1 /path/to/file2
6 }) Y% C: V+ k) w$ D' L# d5 `& b% G3 g3 o: g$ N
递归查找某个目录中所有打开的文件
/ m9 `4 H/ t+ F( w
! |: z  n, M& _  w# lsof +D /usr/lib0 C% M' @# Z5 [0 l. P+ g+ ?2 \

+ u- E* \- [8 e+ V7 l7 u: t加上+D参数,lsof会对指定目录进行递归查找,注意这个参数要比grep版本慢:( J/ N$ z3 k" g* Y4 D" k
; a! u7 T, S: d, N( V
# lsof | grep '/usr/lib'  ^9 @! e" {" u* v, z

- a5 m- J4 r) E, a# o之所以慢是因为+D首先查找所有的文件,然后一次性输出。
/ M* K7 R+ t& Z* Z9 C% Z) M- H# A! S8 w" m0 P( F0 {1 R. F6 C+ h
列出某个用户打开的所有文件: {2 M% u6 i/ @) i
3 J$ z( k6 U0 v/ d6 i- v
# lsof -u pkrumins6 E& k$ w( N- G

% F2 G7 h6 t- G: C8 j! x3 w: W-u选项限定只列出所有被用户pkrumins打开的文件,你可以通过逗号指定多个用户:
5 J1 I* @5 X& w- l
$ k" ?: V  @6 r6 \% h) d# T- A# lsof -u rms,root/ f" ~, K" w/ d4 g0 }
8 c) ?5 q6 j6 a
这条命令会列出所有rms和root用户打开的文件。
% \6 z7 z9 G$ x3 a- o
2 d" K& k, o8 L$ J- s$ i你也可以像下面这样使用多个-u做同样的事情:, A1 E* S& H5 R3 i5 Z2 f/ ~

& p: X+ B: D7 |/ }1 W2 o* {7 T! w# lsof -u rms -u root
$ f$ J, O4 G1 i  f1 T0 r
6 d% M. o2 u# c3 e查找某个程序打开的所有文件
) t0 W- B4 g# H. D% i6 V) S6 ~6 |, ?$ A- Q" u
# lsof -c apache
( ~3 H! x) ?, r; e6 @4 N+ \
; F$ k* k4 }7 e, I( f-c选项限定只列出以apache开头的进程打开的文件:
4 \+ z6 F! ^9 X. d. \& C3 y2 c" Y( D1 z( O
所以你可以不用像下面这样写:
4 N" x' S, W9 A% g4 _5 j* \, Y
9 u7 X( j0 D0 K/ {# lsof | grep foo  ]& x. v- {. k0 g2 p6 x9 t5 p( k
, c* o/ F; w% H" L3 o( S3 l% o- J
而使用下面这个更简短的版本:
% L, ~3 `- N% z* S
1 ^: M' D; ~. s* G1 V9 t3 c# lsof -c foo
* O8 y# M- ?5 |. U2 @9 [5 p! f3 V( a  E* |3 Q  t8 b
事实上,你可以只制定进程名称的开头:  D3 V- [( D! T+ |6 D9 b0 L
4 V! g: A' m  f+ s9 G4 J
# lsof -c apa
% P2 V5 L6 t( ~7 F; \9 [# x* U2 }. p% v9 i& M9 ~* @, V
这会列出所有以apa开头的进程打开的文件
9 D: W; z# E$ x# p) b* S1 G; L* \5 k( p
你同样可以制定多个-c参数:4 z' @% b7 J# u5 }# X% q

( t; |( y8 n$ S9 Y7 `8 D* ]# lsof -c apache -c python
6 d! b5 }8 q0 y" k% Q& A: j6 _
9 `# ~% [; F( W- A5 D1 X这会列出所有由apache和python打开的文件% Z7 k! I1 o+ W" W: b& {8 c2 \
0 V/ b, V8 k1 A7 H
列出所有由某个用户或某个进程打开的文件- @" I) T! \+ r/ i% f( B

- S4 K" h) U% W* Y4 ?$ t" w# lsof -u pkrumins -c apache$ _, K7 R$ x) ?2 }

& t1 \) C8 {8 ]& n/ j$ o6 L5 `. {你也可以组合使用多个选项,这些选项默认进行或关联,也就是说上面的命令会输入由pkrumins用户或是apache进程打开的文件。8 ^8 E) p+ |2 F1 n  a1 L# v  P  q
8 l: J! T2 z: j0 ?* x
列出所有由一个用户与某个进程打开的文件
" W" O( f$ J  Y# `
- ~+ h: Y$ \  }# lsof -a -u pkrumins -c bash  u1 I) k. k; C

0 U3 O) k% Z/ Y+ S# x-a参数可以将多个选项的组合条件由或变为与,上面的命令会显示所有由pkrumins用户以及bash进程打开的文件。
4 Z1 s1 i9 w6 K/ E" K
' o. r' _# ]& }列出除root用户外的所有用户打开的文件
, B" R+ l' \5 L- d9 {6 B8 \3 l- V/ ~( w9 `  F. x
# lsof -u ^root2 h+ @2 [6 j  `& D! B# x# g: O

% u9 N  {( ~0 F注意root前面的^符号,它执行取反操作,因此lsof会列出所有root用户之外的用户打开的文件。1 o  v+ t3 ]8 n( q
' }% ~5 A* p. }* y
列出所有由某个PID对应的进程打开的文件
, _4 b- E' C+ Q% }1 }; s
# H: G' a0 D6 ^. D  O! S, _5 j# lsof -p 1) A0 [6 l! U/ r" A

3 O9 a$ w- r8 [-p选项让你可以使用进程id来过滤输出。4 Q1 @/ D8 i$ c9 P

# N8 X0 ^" I4 @$ G& N+ g记住你也可以用都好来分离多个pid。
* k# H! u& a5 b6 W5 ?  ~
$ u& C% w! z# V* M( ?) o9 z# lsof -p 450,980,333
7 l" h1 b; P: P! k: X) s/ d' V# t: u6 Z! _2 J
列出所有进程打开的文件除了某个pid的
1 \. {* x0 p! ~, q, {. {
9 U/ @# L  n" K$ W9 C# lsof -p ^1& `, j* u# F/ j- k3 R

9 x, O- B3 D' o同前面的用户一样,你也可以对-p选项使用^来进行取反。  s3 ~7 _# @+ {
! ]# h. d+ z( D* T% |$ f+ z2 _* c) V
列出所有网络连接" T1 F4 A4 w9 V6 q. u& j. ]3 y8 P- U
% z5 U  q- r% a( f; _/ Z" q
# lsof -i
3 N4 @$ e1 D. N! V5 E8 N, g; f- S& e
, E' g5 B: I8 g6 ^" o3 _lsof的-i选项可以列出所有打开了网络套接字(TCP和UDP)的进程。
4 H8 n: p4 w$ @5 b* W+ }9 ^8 `( _3 b. i
列出所有TCP网络连接
( i- Z* u3 m# y) D# w+ W7 d* ?9 O0 K6 `  R9 M+ f- w5 o
# lsof -i tcp# m" e% l6 u" z2 \: `7 z( c
% ~9 s* S( H+ J) \+ \) A( O5 t& k
也可以为-i选项加上参数,比如tcp,tcp选项会强制lsof只列出打开TCP sockets的进程。% B+ R- p, _6 q

6 n: T2 I5 q% y7 `; F列出所有UDP网络连接' Q. b& ^5 p& |2 B
: h# Q- W' F! b. V8 s4 k3 q
# lsof -i udp
- M8 u3 k6 ]3 m2 ]8 [( r( e8 t, a6 j2 m, T! w5 A
同样udp让lsof只列出使用UDP socket的进程。
! O6 r/ F) P# N4 w
; d; @0 o& x& S2 ]! S找到使用某个端口的进程3 a. I6 h. e& _7 w7 F6 r5 ^
% [4 ?/ R, p0 I1 o, m
# lsof -i :25
: e7 [( Q- l) I' p0 S3 h, a+ t( ?5 C. \  l1 E5 \( J( M# `
:25和-i选项组合可以让lsof列出占用TCP或UDP的25端口的进程。, Y. ~$ L0 ~% u6 M- j% W
& F' v; e& B/ F( y* \0 Y
你也可以使用/etc/services中制定的端口名称来代替端口号,比如:: L% e8 d' s4 p2 }  F& |  z, Y
% \5 P; D+ f1 A* I
# lsof -i :smtp6 P* n; B, k/ H1 j. {; a: q6 t
& d5 l1 _: \- G/ S. q
找到使用某个udp端口号的进程+ ~( b" ^2 p) B" y# m8 h# S
" H6 J$ X$ e, ?; Z$ k; X
# lsof -i udp:53' I; n$ D& s9 f: P  r0 o6 T

, d: K" G) _: e8 f6 G; a同样的,也可以找到使用某个tcp端口的进程:
! _- q" l' {: _( D7 ~; L0 o
6 }, c9 U4 b: D( T# lsof -i tcp:802 C. e6 q$ F) x" ^2 ?  A  _' e
0 b) `6 s, W3 k2 ^4 g8 P) e1 P
找到某个用户的所有网络连接- Q# u: J8 E* B9 v% @% A* ]3 L: ?" Z

+ y0 u8 R0 W  g# lsof -a -u hacker -i* @: q; @3 L/ W# A6 R8 C, u) i! t: G
7 e4 u, M& |7 B+ K/ _& P
使用-a将-u和-i选项组合可以让lsof列出某个用户的所有网络行为。/ K9 U3 {7 S  R: H6 D3 D
+ |  |; b9 r, C
列出所有NFS(网络文件系统)文件
3 N" M4 H0 _2 H. r( Q3 s; D- U3 e6 g0 u& i' b9 ]
# lsof -N2 l" Q) W2 ^: x5 Y

! x* Z: d4 A  l+ c, I这个参数很好记,-N就对应NFS。# D+ a" N5 h2 r4 L/ U* _0 v% G" m
& o1 P! [4 |1 l5 ~/ {/ v
列出所有UNIX域Socket文件
- y# G" z/ U1 f8 a  _- C, m& k. p& U+ j/ c$ W% s- ?9 E3 w! ~$ P
# lsof -U' I8 x8 P$ m# e4 F- x1 {- v

$ u8 `7 o$ X0 T: A; T% b" E这个选项也很好记,-U就对应UNIX。: {1 [( x1 h2 j: T" f- d9 b

+ C# v4 j" M- g/ _& {$ S列出所有对应某个组id的进程- V( G+ k/ I/ y6 L0 H& M8 S" Q

+ k0 Y1 N. k; c2 }2 _% j6 ~8 N# lsof -g 12346 K% E/ }5 F9 J- g+ T, ]

- _7 \' e5 m( l1 g+ ~. `进程组用来来逻辑上对进程进行分组,这个例子查找所有PGID为1234的进程打开的文件。5 m0 p4 {+ z6 S* _
3 p$ @* n  a9 B! n+ E' k
列出所有与某个描述符关联的文件- R; H8 z4 _, U+ f; H

$ b- v! l& o$ N4 @# lsof -d 2# F4 Y! Y) _, m! o- s: z

) |7 K2 r" G3 k& k+ \1 k! J( Y4 F9 t这个命令会列出所有以描述符2打开的文件。9 \! J4 Y; _" ~4 t8 e& Y

9 r- \0 [& j+ u4 B7 P$ D你也可以为描述符指定一个范围:
/ r8 ]# m" P9 }$ |- G6 _+ H3 j' {7 P2 [1 Q! e- H
# lsof -d 0-2
( y' v* q  s' G/ ?2 E; N
) C% O# c4 _6 i% E1 m这会列出所有描述符为0,1,2的文件。( n# A$ w6 b0 Y! E5 b
1 q; M$ Y1 z$ a" j( J
-d选项还支持其它很多特殊值,下面的命令列出所有内存映射文件:& K. c: V+ @! j

! B' P# V# o# J+ ?8 P# lsof -d mem
6 x. h+ t# p# [* N# \9 c3 V) n
, r$ `+ \, f: Stxt则列出所有加载在内存中并正在执行的进程:3 a" P) i# y: T8 ?! U

, ^7 ^/ x) m8 `6 q2 r# lsof -d txt& N: P; h) Q2 s* n5 Q& g/ \
" b' b. \* s& V3 P
输出使用某些资源的进程pid
- d: W, B4 f9 z! ?1 l
) p$ v9 w* h& ~9 N1 C$ m# lsof -t -i
, M9 X* O4 h- ~+ s6 B
' e4 s* N5 d3 w; m- G; F-t选项输出进程的PID,你可以将它和-i选项组合输出使用某个端口的进程的PID,下面的命令将会杀掉所有使用网络的进程:
9 }- @0 V7 A3 s2 @  j+ y2 w/ D# [* e) S; I+ B$ n3 o8 v
# kill -9 `lsof -t -i`
+ |  ^7 ~5 B. |* `+ ]- H1 j7 {+ I# g5 ^* V. O3 M' x
循环列出文件8 O7 i9 v( \3 i7 L- K( [+ D3 \

# v8 W; P) v$ V/ X1 k! C* D3 ]9 ~# lsof -r 1- Y; P0 B* j( H3 m. ?: D6 g

' i, t0 ?% C; i2 `& [6 ^-r选项让lsof可以循环列出文件直到被中断,参数1的意思是每秒钟重复打印一次,这个选项最好同某个范围比较小的查询组合使用,比如用来监测网络活动:
" A1 W& _8 ]; ?0 _6 y# r  q" H& Y) ^) d/ G& @4 ^
# lsof -r 1 -u john -i -a
7 m( a, \9 T" |& W0 v/ @  z; ^
5 {/ y" J! x* M6 ?, v如何安装lsof?9 I5 p( C# ~, W1 Q' h

) C& e8 z& w- y) k- G许多Unix系统都内置了lsof,如果你的系统没有安装,你可以从这里直接下载源代码。0 ]6 z3 k* {/ R; s8 `
$ B/ z5 n' _; u" x  K
BSD系统有一个类似的工具可以做同样的事情,叫做fstat。
( T1 k( P" o( i, c4 h6 R5 m7 u3 ~1 n3 z
你可以通过man lsof来了解关于lsof的完整文档,或者通过lsof -h查看。
; \3 a1 y( k2 z4 \3 x" ]# Y% @  j* {! Z0 a2 p' r& Y& D
开始体验lsof的乐趣吧!

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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