1- #!/usr/bin/env python
2- # Convert the output of `lsof -F` into PID USER CMD OBJ
1+ #!/usr/bin/env python3
2+
33import sys
4+ from collections import defaultdict
45
56
67def parse_lsof ():
@@ -12,7 +13,7 @@ def parse_lsof():
1213 for line in sys .stdin :
1314
1415 if line .startswith ("COMMAND" ):
15- print 'did you run lsof without -F?'
16+ print ( 'did you run lsof without -F?' )
1617 exit (1 )
1718
1819 tag = line [0 ]
@@ -54,7 +55,7 @@ def find_connections(procs):
5455 'udp' : {},
5556 'pipe' : {}
5657 }
57- for pid , proc in procs .iteritems ():
58+ for pid , proc in procs .items ():
5859 if 'files' in proc :
5960 for _ , file in enumerate (proc ['files' ]):
6061
@@ -121,49 +122,46 @@ def find_connections(procs):
121122
122123
123124def print_graph (procs , conns ):
124- colors = {
125- 'fifo' : "green" ,
126- 'unix' : "purple" ,
127- 'tcp' : "red" ,
128- 'udp' : "orange" ,
129- 'pipe' : "blue"
130- }
125+ colors = defaultdict (lambda : "black" )
126+ colors .update (
127+ {
128+ 'fifo' : "green" ,
129+ 'unix' : "purple" ,
130+ 'tcp' : "red" ,
131+ 'udp' : "orange" ,
132+ 'pipe' : "blue"
133+ }
134+ )
131135
132136 # Generate graph
133137
134138 print ("digraph G {" )
135- print (
136- "\t graph [ center=true, margin=0.2, nodesep=0.1, ranksep=0.3, rankdir=LR];" )
137- print (
138- "\t node [ shape=box, style=\" rounded,filled\" width=0, height=0, fontname=Helvetica, fontsize=10];" )
139+ print ("\t graph [ center=true, margin=0.2, nodesep=0.1, ranksep=0.3, rankdir=LR];" )
140+ print ("\t node [ shape=box, style=\" rounded,filled\" width=0, height=0, fontname=Helvetica, fontsize=10];" )
139141 print ("\t edge [ fontname=Helvetica, fontsize=10];" )
140142
141143 # Parent/child relationships
142144
143- for pid , proc in procs .iteritems ():
145+ for pid , proc in procs .items ():
144146 if 'R' in proc and proc ['R' ] == "1" :
145147 color = "grey70"
146148 else :
147149 color = "white"
148150 if 'p' in proc and 'n' in proc :
149- print ("\t p%s [ label = \" %s\\ n%s %s\" fillcolor=%s ];" %
150- (proc ['p' ], proc ['n' ], proc ['p' ], proc ['L' ], color ))
151+ print (f"\t p{ proc ['p' ]} [ label = \" { proc ['n' ]} \\ n{ proc ['p' ]} { proc ['L' ]} \" fillcolor={ color } ];" )
151152 elif 'p' in proc :
152153 if 'L' in proc : # there could be no L flag if process running, but user was removed. lsof: no pwd entry for UID
153- print ("\t p%s [ label = \" %s\\ n%s %s\" fillcolor=%s ];" %
154- (proc ['p' ], proc ['c' ], proc ['p' ], proc ['L' ], color ))
154+ print (f"\t p{ proc ['p' ]} [ label = \" { proc ['c' ]} \\ n{ proc ['p' ]} { proc ['L' ]} \" fillcolor={ color } ];" )
155155 else :
156- print ("\t p%s [ label = \" %s\\ n%s %s\" fillcolor=%s ];" %
157- (proc ['p' ], proc ['c' ], proc ['p' ], "no user" , color ))
156+ print (f"\t p{ proc ['p' ]} [ label = \" { proc ['c' ]} \\ n{ proc ['p' ]} no user\" fillcolor={ color } ];" )
158157 if 'R' in proc and proc ['R' ] in procs :
159158 proc_parent = procs [proc ['R' ]]
160159 if proc_parent :
161160 if proc_parent ['p' ] != "1" :
162- print (
163- "\t p%s -> p%s [ penwidth=2 weight=100 color=grey60 dir=\" none\" ];" % (proc ['R' ], proc ['p' ]))
161+ print (f"\t p{ proc ['R' ]} -> p{ proc ['p' ]} [ penwidth=2 weight=100 color=grey60 dir=\" none\" ];" )
164162
165- for type , conn in conns .iteritems ():
166- for id , files in conn .iteritems ():
163+ for type , conn in conns .items ():
164+ for id , files in conn .items ():
167165 if len (files ) == 2 :
168166 if files [0 ]['proc' ] != files [1 ]['proc' ]:
169167 label = type + ":\\ n" + id
@@ -172,8 +170,7 @@ def print_graph(procs, conns):
172170 dir = "forward"
173171 elif files [0 ]['a' ] == "r" :
174172 dir = "backward"
175- print ("\t p%s -> p%s [ color=\" %s\" label=\" %s\" dir=\" %s\" ];" % (
176- files [0 ]['proc' ]['p' ], files [1 ]['proc' ]['p' ], colors [type ] or "black" , label , dir ))
173+ print (f"\t p{ files [0 ]['proc' ]['p' ]} -> p{ files [1 ]['proc' ]['p' ]} [ color=\" { colors [type ]} \" label=\" { label } \" dir=\" { dir } \" ];" )
177174 print ("}" )
178175
179176
0 commit comments