kill command in a perl script

H

Hugh Kang

I just started learning Perl and I am trying to do followings;

ps -ef | grep java >pidfile
In pidfile, there are 3 PIDs for weblogic processes.

root 1769 1758 TS 0 0 17:55:26 vt02 44:38
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms512m
-Xmx512m -Dweb
root 27464 27453 TS 29 0 09:15:55 vt04 91:55
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms1024m
-Xmx1024m -Dw
root 27533 27522 TS 49 0 09:21:45 vt03 2:35
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms32m
-Xmx200m -Dwebl

What I want is get the largest PID which is 27533 in this case, and
then
kill -3 the PID.

So I made a simple one for this:

#!/usr/bin/perl
#
# This is a test script to get wls managed server pid
#
#
open(JAVAPIDS,"pidfile") or die "can't open input file:$!\n";
$pidcnt=0;
while($line=<JAVAPIDS>) {
# ($user,$pid1,$pid2,$it4,$it5,$it6,$it7,$it8,$it9,$it10,$it11,$it12,$it13,$it14,$it15)=split("
",$line);
($user,$pid1)=split(" ",$line);
$pidfile{$pid1}=$pid1;
$pid_comp[$pidcnt]=$pidfile{$pid1};
# print "pid$pidcnt : $pid_comp[$pidcnt] \n";
if ($pidcnt gt 0) {
if ($pid_comp[0] < $pid_comp[$pidcnt]) {
$pid_comp[0] = $pid_comp[$pidcnt];
}
}
$pidcnt++;

}
print "pidcnt : $pidcnt \n";
print "Largest PID for java is : $pid_comp[0] \n";

------------------------------------------

Q1) How do I do 'kill -3 $pid_comp[0] in this script?
Q2) Is there any way that I can do the followings:

In a Unix script,

ps -ef |grep java >pidfile

../perl_script
....
....
kill -3 $pid_comp[0]


Q3) Any other way to get what I want?


Can anyone help me out with this issue please?

Many thanks in advance!

Hugh
 
T

Ted Zlatanov

I just started learning Perl and I am trying to do followings;

ps -ef | grep java >pidfile
In pidfile, there are 3 PIDs for weblogic processes.

root 1769 1758 TS 0 0 17:55:26 vt02 44:38
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms512m
-Xmx512m -Dweb
root 27464 27453 TS 29 0 09:15:55 vt04 91:55
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms1024m
-Xmx1024m -Dw
root 27533 27522 TS 49 0 09:21:45 vt03 2:35
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms32m
-Xmx200m -Dwebl

What I want is get the largest PID which is 27533 in this case, and
then kill -3 the PID.

Use Proc:processTable from CPAN.

<offtopic>
I should warn you that the "largest" PID is meaningless - new
processes do not necessarily have larger PIDs than older processes on
any OS I have used, including Linux. You should find a better way to
discover the process you want to kill. You could use the daemontools
package, for instance.
</offtopic>

Ted
 
H

Hugh Kang

Jim Gibson said:
Hugh Kang said:
I just started learning Perl and I am trying to do followings;

ps -ef | grep java >pidfile
In pidfile, there are 3 PIDs for weblogic processes.

root 1769 1758 TS 0 0 17:55:26 vt02 44:38
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms512m
-Xmx512m -Dweb
root 27464 27453 TS 29 0 09:15:55 vt04 91:55
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms1024m
-Xmx1024m -Dw
root 27533 27522 TS 49 0 09:21:45 vt03 2:35
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms32m
-Xmx200m -Dwebl

What I want is get the largest PID which is 27533 in this case, and
then
kill -3 the PID.

So I made a simple one for this:

#!/usr/bin/perl
#
# This is a test script to get wls managed server pid
#
#
open(JAVAPIDS,"pidfile") or die "can't open input file:$!\n";
$pidcnt=0;
while($line=<JAVAPIDS>) {
#
($user,$pid1,$pid2,$it4,$it5,$it6,$it7,$it8,$it9,$it10,$it11,$it12,$it13,$it14,
$it15)=split("
",$line);

The above line is unnecessary because of the following line.
($user,$pid1)=split(" ",$line);
$pidfile{$pid1}=$pid1;
$pid_comp[$pidcnt]=$pidfile{$pid1};
# print "pid$pidcnt : $pid_comp[$pidcnt] \n";
if ($pidcnt gt 0) {
if ($pid_comp[0] < $pid_comp[$pidcnt]) {
$pid_comp[0] = $pid_comp[$pidcnt];
}
}
$pidcnt++;

}
print "pidcnt : $pidcnt \n";
print "Largest PID for java is : $pid_comp[0] \n";

kill 3, $pid_comp[0]

See 'perldoc -f kill'
Q2) Is there any way that I can do the followings:

In a Unix script,

ps -ef |grep java >pidfile

./perl_script
...
...
kill -3 $pid_comp[0]

Not easily, and not necessary because of answer to 1.
Q3) Any other way to get what I want?

Yes. You can get the filtered output of the ps command using backtics:

[tested in part ("No processes were actually killed in the development
of this program")]

#!/opt/perl/bin/perl

use strict;
use warnings;

my @lines = `ps -ef|grep java`; # <--notice backtics, not single quotes
my @pids = ();
foreach ( @lines) {
my ($user,$pid) = split;
push(@pids,$pid);
}
my $largest = ((sort(@pids)))[$#pids];
kill 3, $largest;

[end program]
Can anyone help me out with this issue please?

Hope I have.
Many thanks in advance!

Hugh



Thanks a lot. I have three more things to ask please.

q1) When I do my @lines = `ps -ef | grep java`;, pid for "grep java" from ps -ef
is included in @lines. I'd like to exclude this one. How do I do that?
When I do, ps -ef | grep java > pidfile on Unix shell, I don't see the pid
for 'grep java' in pidfile.

q2) Later I'd like to check the 11th column which can be "-Xms1024m" and issue
kill -3 $pid if it is "-Xms1024m". How do I check it using the above script?

q3) kill -3 $pid is not killing the process. It makes a thread dump for weblogic
server. In Unix script, I check an error from log file and want to take a
thread dump using the perl script when the error occurs. How can I run the perl
script in Unix script? Or any other way to do this?


I just ordered Perl manuals to study and practice more.

Thanks again.

Hugh
 
J

John W. Krahn

Hugh said:
q1) When I do my @lines = `ps -ef | grep java`;, pid for "grep java" from ps -ef
is included in @lines. I'd like to exclude this one. How do I do that?
When I do, ps -ef | grep java > pidfile on Unix shell, I don't see the pid
for 'grep java' in pidfile.

my @lines = grep /java/, `ps -ef`;

Or if you just want the PIDs and have the appropriate version of ps or
pgrep:

my @pids = `ps h -C java -o pid`;

my @pids = `pgrep java`;

q2) Later I'd like to check the 11th column which can be "-Xms1024m" and issue
kill -3 $pid if it is "-Xms1024m". How do I check it using the above script?

My version of "ps -ef" doesn't have eleven columns

kill 'QUIT', grep { /-Xms1024m/ and $_ = (split)[0] } `ps h -C java -o
pid,command`;

q3) kill -3 $pid is not killing the process.

You do realise that using a negative number with kill is different then
using a positive number.

perldoc -f kill
[snip]
Unlike in the shell, if SIGNAL is negative, it
kills process groups instead of processes. (On
System V, a negative PROCESS number will also kill
process groups, but that's not portable.) That
means you usually want to use positive not
negative signals. You may also use a signal name
in quotes. See the Signals entry in the perlipc
manpage for details.



John
 
T

Ted Zlatanov

[lots of awkward ps -ef gymnastics omitted]

Good god, guys, why are you stubbornly trying to reinvent the wheel?
I mean, it's fun to do it sometimes, but Hugh (a new Perl programmer)
should absolutely not be trying to manually parse the output of
ps -ef, creating a nonportable script with weird bugs (what happens
if "grep" is in the process name you want, for instance? what happens
on systems where ps -ef does not do what you think it does?)

Please use Proc::processTable from CPAN. It will save you time and
lots of headaches.

Ted
 
J

John W. Krahn

Ted said:
[lots of awkward ps -ef gymnastics omitted]

Good god, guys, why are you stubbornly trying to reinvent the wheel?
I mean, it's fun to do it sometimes, but Hugh (a new Perl programmer)
should absolutely not be trying to manually parse the output of
ps -ef, creating a nonportable script with weird bugs (what happens
if "grep" is in the process name you want, for instance? what happens
on systems where ps -ef does not do what you think it does?)

Please use Proc::processTable from CPAN. It will save you time and
lots of headaches.

$ cat Proc-ProcessTable-0.38/README
Proc::processTable, version .38

STATUS
======
This is BETA software; it seems to work, but use at your own risk :)
[snip]


If that's not enough of a reason the module requires a C compiler to
install and all the C code does (on FreeBSD, IRIX, DecOSF, NetBSD,
Linux, UnixWare and Solaris) is access the /proc file system


A code example from ProcessTable.pm

sub _get_tty_list
{
my ($self) = @_;
undef %Proc::processTable::TTYDEVS;
find({ wanted =>
sub{
$File::Find::prune = 1 if -d $_ && ! -x $_;
my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks) =
stat($File::Find::name);
$Proc::processTable::TTYDEVS{$rdev} = $File::Find::name
if(-c $File::Find::name);
}, no_chdir => 1},
"/dev"
);
}


Why are they stat()ing the same file FOUR times?


Not that I'm against using modules. :) I just like to know what all
my options are.


John
 
B

Barry Kimelman

[This followup was posted to comp.lang.perl.misc]

I just started learning Perl and I am trying to do followings;

ps -ef | grep java >pidfile
In pidfile, there are 3 PIDs for weblogic processes.

root 1769 1758 TS 0 0 17:55:26 vt02 44:38
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms512m
-Xmx512m -Dweb
root 27464 27453 TS 29 0 09:15:55 vt04 91:55
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms1024m
-Xmx1024m -Dw
root 27533 27522 TS 49 0 09:21:45 vt03 2:35
/opt/java2-1.3.1/bin/./../bin/x86at/native_threads/java -Xms32m
-Xmx200m -Dwebl

What I want is get the largest PID which is 27533 in this case, and
then
kill -3 the PID.

So I made a simple one for this:

#!/usr/bin/perl
#
# This is a test script to get wls managed server pid
#
#
open(JAVAPIDS,"pidfile") or die "can't open input file:$!\n";
$pidcnt=0;
while($line=<JAVAPIDS>) {
# ($user,$pid1,$pid2,$it4,$it5,$it6,$it7,$it8,$it9,$it10,$it11,$it12,$it13,$it14,$it15)=split("
",$line);
($user,$pid1)=split(" ",$line);
$pidfile{$pid1}=$pid1;
$pid_comp[$pidcnt]=$pidfile{$pid1};
# print "pid$pidcnt : $pid_comp[$pidcnt] \n";
if ($pidcnt gt 0) {
if ($pid_comp[0] < $pid_comp[$pidcnt]) {
$pid_comp[0] = $pid_comp[$pidcnt];
}
}
$pidcnt++;

}
print "pidcnt : $pidcnt \n";
print "Largest PID for java is : $pid_comp[0] \n";


Perl has a "kill" function. For more details do the following :

perldoc -f kill
 
D

Daniel Berger

John W. Krahn said:
Ted said:
[lots of awkward ps -ef gymnastics omitted]

Good god, guys, why are you stubbornly trying to reinvent the wheel?
I mean, it's fun to do it sometimes, but Hugh (a new Perl programmer)
should absolutely not be trying to manually parse the output of
ps -ef, creating a nonportable script with weird bugs (what happens
if "grep" is in the process name you want, for instance? what happens
on systems where ps -ef does not do what you think it does?)

Please use Proc::processTable from CPAN. It will save you time and
lots of headaches.

$ cat Proc-ProcessTable-0.38/README
Proc::processTable, version .38

STATUS
======
This is BETA software; it seems to work, but use at your own risk :)
[snip]

Dan should really remove that. His code has been around long enough,
and is stable enough, that I consider it production quallity. Having
ported some of his code to Ruby, I can tell you that it's trustworthy,
i.e. passes all tests, no memory leaks, and does what it's supposed to
do.
If that's not enough of a reason the module requires a C compiler to
install and all the C code does (on FreeBSD, IRIX, DecOSF, NetBSD,
Linux, UnixWare and Solaris) is access the /proc file system

It requires a C compiler - so what? If you're on *BSD or Linux,
you've almost certainly have gcc anyway. Solaris users will likely
have some compiler (gcc or Sun's Forte compiler). I can't speak for
UnixWare, IRIX or DecOSF.

In addition, reading out of /proc for Linux and *BSD is simple enough
with pure Perl, but it will still be faster with C. Parsing /proc
with pure Perl would be quite a challenge on Solaris, considering that
the information in /proc is NOT in plaintext format.
A code example from ProcessTable.pm

sub _get_tty_list
{
my ($self) = @_;
undef %Proc::processTable::TTYDEVS;
find({ wanted =>
sub{
$File::Find::prune = 1 if -d $_ && ! -x $_;
my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks) =
stat($File::Find::name);
$Proc::processTable::TTYDEVS{$rdev} = $File::Find::name
if(-c $File::Find::name);
}, no_chdir => 1},
"/dev"
);
}


Why are they stat()ing the same file FOUR times?

Hmm....I don't remember this code, so I can't say much about it. The
author, Dan Urist, would probably be willing to explain this code if
you ask him.
Not that I'm against using modules. :) I just like to know what all
my options are.


John

Your choices are to parse 'ps' (blech) or use Proc::processTable. As
others have noted, parsing ps is utterly unreliable and not portable
because the options are different on different platforms, and
sometimes they're different on the *same* platform between releases.
You can always submit pure Perl patches to Dan for Linux and the *BSD
family if the C compiler thing really bothers you that much. Wouldn't
be that difficult.

If there's any "flaw" to Dan's code it's that he added the formatting
cruft, presumably because ps gives you output formatting options.
I'll bet if he had to do it over again, he would rip that out, but
that's just a guess. I can tell you that *I* will never add it. :)

Regards,

Dan (Berger)
 
B

Bart Lateur

Ted said:
I should warn you that the "largest" PID is meaningless - new
processes do not necessarily have larger PIDs than older processes on
any OS I have used, including Linux.

Indeed. The reason is simple: wraparound beyond a fixed number of bits
for the ID numbers. So after a while they start back at zero. (Or 1...?)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top