-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmurder
executable file
·83 lines (66 loc) · 1.39 KB
/
murder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env ruby
SIGNALS = [
[15, 3],
[2, 3],
[1, 4],
[9, 0]
]
def i?(arg)
arg.to_i != 0
end
def running?(pid)
`ps -p #{pid}`.lines.length == 2
end
def go_ahead?
%w(y yes yas).include? $stdin.gets.strip.downcase
end
def kill(pid, code)
`kill -#{code} #{pid}`
end
def murder_pid(pid)
SIGNALS.each do |signal|
break unless running? pid
code, wait = signal
kill(pid, code)
sleep 0.5
sleep(wait) if running? pid
end
end
def murder_names(name)
running = `ps -eo 'pid command' | grep -Fiw '#{name}' | grep -Fv grep`
running.lines.each do |line|
pid, fullname = line.split(nil, 2)
next if Process.pid == pid.to_i
print "murder #{fullname.chomp} (pid #{pid})? "
murder_pid(pid) if go_ahead?
end
end
def murder_port(arg)
lsofs = `lsof -i #{arg}`
lsofs.lines.drop(1).each do |line|
pid = line.split(nil, 3)[1]
fullname = `ps -eo 'command' #{pid}`.lines.drop(1).first
print "murder #{fullname.chomp} (pid #{pid})? "
murder_pid(pid) if go_ahead?
end
end
def main(arg)
is_pid = i?(arg)
is_port = arg[0] == ':' && i?(arg.slice(1, arg.size))
if is_pid
murder_pid arg
elsif is_port
murder_port arg
else
murder_names arg
end
end
if ARGV.size < 1
puts 'usage:'
puts 'murder 123 # kill by pid'
puts 'murder ruby # kill by process name'
puts 'murder :3000 # kill by port'
exit 1
else
main(ARGV[0])
end