例えばRailsでmongrel動かしているとき。なぜかmongrel_rails cluster::restart とやっても再起動しないことがありました。あとrubyで複数のmongrelを使ってるときいつのまにかport埋まってていちいちpid特定してkillするのも面倒です。
で、なんとかしてRuby使ってportkillできないかなーとか思って調べてみたんですが直接Rubyでプロセスをいじれるようなメソッドが見つからなかったので(どなたかもし知っていればぜひ教えてください。)systemコマンドのlsofというコマンドというものを使うことにしました。
詳しくはmanとかで見てもらうとして、実用的そうなのは以下のコマンドです。
lsof -i -n -P
このコマンドで少なくともDebian etch環境では
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 2368 root 3u IPv4 8087 0t0 TCP *:22 (LISTEN)
sshd 2368 root 4u IPv6 8089 0t0 TCP *:22 (LISTEN)
という風に出てきます。
ただし、root権限で実行しないとすべてがでてきません。一般ユーザー権限で実行するとその実行したユーザーが現在ポートを使っているプログラムしか出てきません。
これを使って適当にプログラムを書きました。
(結構オレオレ仕様が入っています。rootでしか使えないのはちょっとやりすぎですかね。。@個人的練習のためにgithub(http://github.com/syou/tools)にもおいてあります。)
注意:このプログラムはENV使ってます。ENV環境はそれぞれのディストリビューションによって違う可能性があります。
#!/usr/bin/ruby
require 'optparse'
#raise ENV["USER"].inspect
#raise ENV["_"].inspect
##############################################
# portkill.rb 09/05/01
# Usage: portkill.rb -p PORT
# (Only root can run this program.)
#############################################
unless ENV["USER"] == "root"
puts "root required.(please su or sudo!)"
exit(-1)
end
port = 0
ARGV.options do |opt|
opt.on('-p PORT', 'port number.'){ |v| port = v.to_i }
opt.parse!
end
if port.to_i.zero?
puts "Usage: portkill [options] \n\t-p PORT\t port number."
exit(-1)
end
puts "port #{port} process is searching now..."
finds = []
first_line = nil
ports = %x(lsof -i -n -P).split(/\n/)
ports.each_with_index do |port_line, i|
if i.zero?
first_line = port_line
next
end
split_line = port_line.split(/\s+/)
_port = nil
#raise line.inspect
split_line.each do |s|
if s.split(":").size > 1
_port = s.split(":")[1].to_i
#tmps << _port
end
end
if _port == port
finds << { :description => port_line, :port => _port, :pid => split_line[1].to_i }
end
end
if finds.empty?
puts "port #{port} process doesn't find in all proceses!"
exit(0)
end
puts "find #{finds.size} count processes."
puts first_line
finds.each{ |k| puts "[find] #{k[:description]}"}
finds.each do |f|
puts "#{f[:pid]} is killing now.."
%x(kill #{f[:pid]})
end
puts "done."
exit(0)
これでどんどんkillできるー(だめだけど)apacheでも何でも
0 件のコメント:
コメントを投稿