BEGIN {
*gettimeofday = eval { require Time::HiRes } ?
\&Time::HiRes::gettimeofday :
sub { (time, 0) };
}
use Getopt::Long;
Getopt::Long::config qw(bundling no_getopt_compat);
my( $opt, @opt, %opt, @kill );
sub opt($$) { push @opt, "-$_[0]$_[1]" }
sub p_args { for( $ENV{"P_ARGS_$_[0]"} ) { defined or die "$0: \$P_ARGS_$_[0] not set\n"; push @ARGV, split } }
GetOptions \%opt,
qw'a b=s C d D=f e E f F I j k+ l L N P S T v w W',
'i' => sub { push @opt, '-u', $< },
'K=s' => \@kill,
'o=s' => sub { push @opt, ($_[1] =~ /\bpid\b/) ? "-o$_[1]" : "-opid,$_[1]" },
'p=s' => \&opt,
'r' => sub { push @opt, '-uroot' },
't=s' => \&opt,
'u=s' => \&opt,
0 => sub { push @ARGV, '-fwdD0' },
1 => sub { push @ARGV, '-fwd' },
2 => sub { push @ARGV, '-fFw' },
map( ($_ => \&p_args), 3..9 ),
'help|?' => sub { print STDERR <<'EOF'; exit };
usage: p[ -aefIjlLrkdv -o<opt> -u<user> -p<pid> -t<tty> -K<sig> -D<seconds> -b<bsdopt>][ regexp ...]
-i show my processes
-r show root processes
-k kill, repeat suppresses question
-K kill with signal, can be repeated and -k suppresses question
-C sorted by CPU
-E sorted by executing command
-F sorted by father process, shown as a tree, can be combined with other sort
-I sorted by process ID
-N sorted by nice
-P sorted by prio
-S sorted by size
-T sorted by start time
-d diff (default: every second)
-D diff or loop time interval
-v vice versa, show processes not matching regexps
-b call bsd/ucb ps with bsd options
-w cut to $COLUMNS (default 132)
-0 -fwdD0 (0secs)
-1 -fwd (1sec)
-2 -fFw (tree 2 width)
-3..-9 $P_ARGS_3..$P_ARGS_9
EOF
push @opt, "-$opt"
if $opt = join '', grep $opt{$_}, qw'a e f j l L';
my $optD = defined( $opt{D} ) ? $opt{D} : 1;
$opt{w} &&= $ENV{COLUMNS} || 132 and $ENV{COLUMNS} = $opt{w} + 4; # Gnu ps does less than COLUMNS :-(
my $re = 0;
if( @ARGV ) {
local $" = '|';
$re = qr/@ARGV/;
}
# normal single shot operation
print $head . &output;
if( $opt{k} || @kill ) {
my @pids = map { int substr $_, $pidcol } @ps;
my $kill = ($opt{k} > 1 or $opt{k} && @kill);
unless( $kill ) {
local $| = 1;
$kill = join ' -', '', @kill;
print "kill$kill @pids? ";
$kill = (<STDIN> =~ /^[jy]/); # Esperanto and English
}
if( $kill ) {
@kill = 15 unless @kill;
kill $_ => @pids for @kill;
goto AGAIN;
}
}
__END__
=head1 ps wrapper
=over 4
=item *
adapts to various variants of ps (tested on Linux, Solaris, AIX, HP/UX &
Reliant Unix)
=item *
sorts by pid or other column you specify
=item *
allows killing the selected processes with any signal
=item *
eliminates itself and ps process from output
=item *
options for all own (-i) or root's (-r) processes
=item *
allows grepping processes (optionally inversely) with Perl regexps
=item *
father mode (-F) for showing a process tree
=item *
eliminates C column, which is by definition useless
=item *
loop mode repeatedly outputs every n (fractional) seconds, specially optimized
for 0 seconds to loop as fast as possible -- interesting when grepping for
running and/or runnable processes
=item *
loop mode with diff to previous output allows tracking processes as they appear
(+) and dissapear (-) or change in some dispayed parameter
=back
=begin CPAN
=head1 README
B<ps wrapper>
B<�� >sort by pid or other column
B<�� >skip self and ps
B<�� >grep (-v)
B<�� >tree
B<�� >can kill selected processes
B<�� >loop mode (with diff)