プロセス検索スクリプト

今回は、psコマンドなどでPIDを調べてkillするのが面倒な場合などに便利なスクリプトを紹介しようと思う。

例えば、killしたいプロセスの名前がある程度分かっている場合などで便利だ。

まずは、実行結果を簡単に説明していこう。

基本的には、

検索→マッチしたプロセスを全て消すか選択して消すか→繰り返し・・・→終了

といったように、対話的に実行していく。

$ ./process_search_kill.pl
Argv error.
$ ./process_search_kill.pl irc

PID     Deny(*) (PROCESS INFO)
=========================
3756    *       (root      3756  0.0  0.4   .* ircd -c)
6870    *       (root      6870  0.0  0.9   .* ./irc_write_httpd.pl)
8111            (500       8111  0.0  0.9   .* ./irc_write_message.pl)
8112            (500       8112  0.0  0.9   .* ./irc_write_secure.pl)
8942    *       (root      8942  0.0  0.9   .* ./irc_write_httpd.pl)
8943    *       (root      8943  0.0  0.9   .* ./irc_write_httpd.pl)
=========================
( * :Permission deny or killing now)

PID is accessible:      8111 8112
PID is not accessible:  3756 6870 8942 8943

kill above all/select process except * ?[all/select/finish]:select
Select[finish/PID is alive].
[8111 8112 finish]:8111
kill 8111

PID     Deny(*) (PROCESS INFO)
=========================
3756    *       (root      3756  0.0  0.4   .* ircd -c)
6870    *       (root      6870  0.0  0.9   .* ./irc_write_httpd.pl)
8112            (500       8112  0.0  0.9   .* ./irc_write_secure.pl)
8942    *       (root      8942  0.0  0.9   .* ./irc_write_httpd.pl)
8943    *       (root      8943  0.0  0.9   .* ./irc_write_httpd.pl)
=========================
( * :Permission deny or killing now)

PID is accessible:      8112
PID is not accessible:  3756 6870 8942 8943

Select[finish/PID is alive].
[8112 finish]:finish

$

このように、第一引数に検索文字列を指定し、実行すると、文字列に一致するプロセス一覧が表示される。

そして、実行したユーザーがアクセス不可なプロセスには「*」が付けられる。

これで、「all」によって、アクセス可能なプロセスを全てkillするか、「select」によってプロセスを選択しながらkillしていくことができる。

最後は「finish」で終了する。

結構単純なスクリプトだが、意外と便利だ。

以下にソースを示す。

#!/usr/bin/perl

use strict;
#use warnings;

my @pid;
my ($input, $line);

if($#ARGV != 0)
{
die("Argv error.\n");
}

my $MATCH_PATTERN = $ARGV[0];
my $NO_MATCH_PATTERN = "process_search_kill.pl";

@pid = &process_chk($MATCH_PATTERN, $NO_MATCH_PATTERN);

while(1)
{
print "kill above all/select process except * ?[all/select/finish]:";
$input = <STDIN>;
chomp($input);

if($input eq "all")
{
print "kill @pid\n";
kill 0 => @pid;
exit;
}
elsif($input eq "select")
{
while(1)
{
print "Select[finish/PID is alive].\n[@pid finish]:";
$input = <STDIN>;
chomp($input);

if($input eq "finish")
{
exit;
}
else
{
foreach $line (@pid)
{
if($input eq $line)
{
kill(1,$input);
print "kill $input\n"
}
}

@pid = &process_chk($MATCH_PATTERN, $NO_MATCH_PATTERN);
}
}
}
elsif($input eq "finish")
{
exit;
}
else
{
print "input error.\n";
}
}

sub process_chk
{
local(*MATCH_PATTERN, *NO_MATCH_PATTERN) = $_;
my (@match_line, @pid, @pid_error);
my $line;
my @all_process = `ps aux`;
my $i = 0;
my $j = 0;

print "\n";
print "PID\tDeny(*)\t(PROCESS INFO)\n";
print "=========================\n";

foreach $line (@all_process)
{
if(($line =~ /$MATCH_PATTERN/) and ($line !~ /$NO_MATCH_PATTERN/))
{
@match_line = split(/ +/, $line);
$pid[$i] = $match_line[1];
chomp($line);

if(kill 0 => $pid[$i])
{
print "$pid[$i]\t\t($line)\n";
$i++;
}
else
{
print "$pid[$i]\t*\t($line)\n";
$pid_error[$j] = $pid[$i];
pop(@pid);
$j++;
}
}
}

print "=========================\n";
print "( * :Permission deny or killing now)\n";

print "\n";
print "PID is accessible:\t@pid\n";
print "PID is not accessible:\t@pid_error\n\n";
if(@pid)
{
return @pid;
}
else
{
print "No PID is accessible.\n";
exit;
}
}