killing processes using perl (artsd)

A

andreas

Hello all,

I'm using an unstable debian distribution (Debian 2.6.18-3) and at some
day I found several artsd processes running in the process list. Normally
there should be only one sound server.

Now I started thinking about how to reduce the artsd process count using a
perl script and wrote something which works and can possibly be used to
remove any processes (cron etc.)

#!/usr/bin/perl -w
# file: killartsd.pl
# kill additional artsd processes - only one is required!
# (c)2006 Andreas Mueller andreas%at%poipoi.de
#####################################

# get artsd process ids from ps piped into a sed script
$plist=qx'ps h -C artsd | sed "s/\(\([ 0-9]*\|[0-9]*\).*\)/\2/g"';

# remove space+newline to form a list of pids
$plist =~ s/ \n/,/g;

# remove the ugly last comma in that list $plength=length($plist);
$plist=substr($plist,0,$plength-1) unless $plength < 1 ;

# convert result to an array because kill() wants an array, isn't it?
@parray=split(/,/,$plist);

# how many process ids are there?
$numproc=@parray;

# kill all unless there is only one or none
kill ('KILL',@parray) unless $numproc < 2 ;

My question is whether one knows a better way to do the whole thing
or parts of the script?

best regards
-andreas
 
M

Mumia W. (reading news)

Hello all,

I'm using an unstable debian distribution (Debian 2.6.18-3) and at some
day I found several artsd processes running in the process list. Normally
there should be only one sound server.

Now I started thinking about how to reduce the artsd process count using a
perl script and wrote something which works and can possibly be used to
remove any processes (cron etc.)

#!/usr/bin/perl -w
# file: killartsd.pl
# kill additional artsd processes - only one is required!
# (c)2006 Andreas Mueller andreas%at%poipoi.de
#####################################

# get artsd process ids from ps piped into a sed script
$plist=qx'ps h -C artsd | sed "s/\(\([ 0-9]*\|[0-9]*\).*\)/\2/g"';

# remove space+newline to form a list of pids
$plist =~ s/ \n/,/g;

# remove the ugly last comma in that list $plength=length($plist);
$plist=substr($plist,0,$plength-1) unless $plength < 1 ;

# convert result to an array because kill() wants an array, isn't it?
@parray=split(/,/,$plist);

# how many process ids are there?
$numproc=@parray;

# kill all unless there is only one or none
kill ('KILL',@parray) unless $numproc < 2 ;

My question is whether one knows a better way to do the whole thing
or parts of the script?

best regards
-andreas

#!/bin/sh
PIDLIST=`ps h -C artsd -o %p`
for arpid in $PIDLIST
do
echo "Would kill $arpid"
done
--------------------------
#!/usr/bin/perl
use strict;
use warnings;
use Carp qw(carp croak);
my @pids = `ps h -C mysqld` =~ m/^ +(\d+)/mg;
print "PIDS: @pids\n";
kill (15, $_) or carp("Failure: $! for $_")
for (@pids);

__END__

Note: the second program (in Perl) attempts to kill mysqld.
 
M

Mumia W. (reading news)

Hello all,

I'm using an unstable debian distribution (Debian 2.6.18-3) and at some
day I found several artsd processes running in the process list. Normally
there should be only one sound server.

Now I started thinking about how to reduce the artsd process count
using a
perl script and wrote something which works and can possibly be used to
remove any processes (cron etc.)

#!/usr/bin/perl -w
# file: killartsd.pl
# kill additional artsd processes - only one is required! # (c)2006
Andreas Mueller andreas%at%poipoi.de
#####################################

# get artsd process ids from ps piped into a sed script $plist=qx'ps h
-C artsd | sed "s/\(\([ 0-9]*\|[0-9]*\).*\)/\2/g"';

# remove space+newline to form a list of pids $plist =~ s/ \n/,/g;

# remove the ugly last comma in that list $plength=length($plist);
$plist=substr($plist,0,$plength-1) unless $plength < 1 ;

# convert result to an array because kill() wants an array, isn't it?
@parray=split(/,/,$plist);

# how many process ids are there?
$numproc=@parray;

# kill all unless there is only one or none
kill ('KILL',@parray) unless $numproc < 2 ;

My question is whether one knows a better way to do the whole thing
or parts of the script?

best regards
-andreas

#!/bin/sh
PIDLIST=`ps h -C artsd -o %p`
for arpid in $PIDLIST
do
echo "Would kill $arpid"
done
--------------------------
#!/usr/bin/perl
use strict;
use warnings;
use Carp qw(carp croak);
my @pids = `ps h -C mysqld` =~ m/^ +(\d+)/mg;
print "PIDS: @pids\n";
kill (15, $_) or carp("Failure: $! for $_")
for (@pids);

__END__

Note: the second program (in Perl) attempts to kill mysqld.

Uhhh, I wish all news-servers supported cancels. The programs I wrote
kill all the servers--not only the extra ones.

Let me try that again:

#!/bin/sh
PIDLIST=`ps h -C artsd -o %p | sed -ne '2,$p'`
for arpid in $PIDLIST
do
echo "Would kill $arpid"
done
-----------------------------------
#!/usr/bin/perl
use strict;
use warnings;
use Carp qw(carp croak);
my @pids = `ps h -C artsd` =~ m/^ +(\d+)/mg;
shift @pids;
print "PIDS: @pids\n";
kill (15, $_) or carp("Failure: $! for $_")
for (@pids);
 
D

Dr.Ruud

andreas schreef:

Now I started thinking about how to reduce the artsd process count
using a perl script and wrote something which works and can possibly
be used to remove any processes (cron etc.)

#!/usr/bin/perl -w
# file: killartsd.pl
# kill additional artsd processes - only one is required!
# (c)2006 Andreas Mueller andreas%at%poipoi.de
#####################################

Remove the -w, and add:

use warnings ;
use strict ;
# get artsd process ids from ps piped into a sed script
$plist=qx'ps h -C artsd | sed "s/\(\([ 0-9]*\|[0-9]*\).*\)/\2/g"';

Whitespace is cheap. The sed-stuff can also be done in Perl of course.
See "Pipe Opens" in perlopentut.

That regex doesn't mean what you think it means. Compare to:
s/ *\([0-9]*\).*/\1/g

# remove space+newline to form a list of pids
$plist =~ s/ \n/,/g;

# remove the ugly last comma in that list $plength=length($plist);
$plist=substr($plist,0,$plength-1) unless $plength < 1 ;

# convert result to an array because kill() wants an array, isn't it?
@parray=split(/,/,$plist);

In stead of the 8 lines above, try this:

my @parray = split / \n/, $plist ;

# how many process ids are there?
$numproc=@parray;

# kill all unless there is only one or none
kill ('KILL',@parray) unless $numproc < 2 ;

My question is whether one knows a better way to do the whole thing
or parts of the script?



#!/usr/bin/perl
use warnings ;
use strict ;

my @pids = do
{ local $/ ;
open my $ph, '-|', 'ps h -C artsd' or die "open ps: $!" ;
<$ph> =~ m/^ *([0-9]+)/gm ;
} ;

print "Pa: ", getppid(), "\n" ;
print "Me: $$\n\n" ;
print "kill '$_'\t?\n" for @pids ;
 
A

andreas

Am Wed, 01 Nov 2006 06:58:41 +0000 schrieb Mumia W. (reading news):
#!/bin/sh
PIDLIST=`ps h -C artsd -o %p | sed -ne '2,$p'`
for arpid in $PIDLIST
do
echo "Would kill $arpid"
done
-----------------------------------
#!/usr/bin/perl
use strict;
use warnings;
use Carp qw(carp croak);
my @pids = `ps h -C artsd` =~ m/^ +(\d+)/mg;
shift @pids;
print "PIDS: @pids\n";
kill (15, $_) or carp("Failure: $! for $_")
for (@pids);


Hello Mumia,

thanks for the Carp & shift hints. To use \d+ is a good idea. If I insert a
debug print @pids; just after line my @pids...; and before the shift.. the
printed line ist empty, at least on my system. There is one artsd running
currently. I'm using perl, v5.8.8. I will play with your solution and try
to get it running even on my system ;-)

-andreas
 
A

andreas

Am Wed, 01 Nov 2006 08:44:04 +0100 schrieb Dr.Ruud:
andreas schreef:



Remove the -w, and add:

use warnings ;
use strict ;

ok - I will look for that and try to figure out why?
# get artsd process ids from ps piped into a sed script
$plist=qx'ps h -C artsd | sed "s/\(\([ 0-9]*\|[0-9]*\).*\)/\2/g"';

Whitespace is cheap. The sed-stuff can also be done in Perl of course.
See "Pipe Opens" in perlopentut.

That regex doesn't mean what you think it means. Compare to:
s/ *\([0-9]*\).*/\1/g

yes - I found the redundancy a little later and corrected it in version
1.01 ;-) thanks!
currently I use:
$plist=qx'ps h -C artsd | sed "s/\(\([ 0-9]*\).*\)/\2/g"';
I know that [ 0-9]* is not fully correct, but because there is an process
name after the pid the pattern stops with the disadvantage of capturing
additional spaces (or a tab?) before and after the pid. Your solution is
better for this reason.
In stead of the 8 lines above, try this:

my @parray = split / \n/, $plist ;

very good!
# how many process ids are there?
$numproc=@parray;

# kill all unless there is only one or none kill ('KILL',@parray)
unless $numproc < 2 ;

My question is whether one knows a better way to do the whole thing or
parts of the script?



#!/usr/bin/perl
use warnings ;
use strict ;

my @pids = do
{ local $/ ;
open my $ph, '-|', 'ps h -C artsd' or die "open ps: $!" ; <$ph> =~
m/^ *([0-9]+)/gm ;
} ;

print "Pa: ", getppid(), "\n" ;
print "Me: $$\n\n" ;
print "kill '$_'\t?\n" for @pids ;

works fine! I've learnt a lot from that, will study the special variables
later - many thanks!!
-andreas
 
A

andreas

Am Wed, 01 Nov 2006 08:44:04 +0100 schrieb Dr.Ruud:
print "kill '$_'\t?\n" for @pids ;

Hello again,

this use of 'for' is not only perl it is a pearl !
Could be the death of 'foreach' ;-)

thanks!
-andreas
 
T

Tad McClellan

andreas said:
Am Wed, 01 Nov 2006 08:44:04 +0100 schrieb Dr.Ruud:

ok - I will look for that and try to figure out why?


Short version:

Because they catch many common programmer mistakes, such as typos.
 
D

Dr.Ruud

andreas schreef:
Dr.Ruud:

this use of 'for' is not only perl it is a pearl !
Could be the death of 'foreach' ;-)

<quote source="perlsyn(1)">
The "foreach" keyword is actually a synonym for the "for" keyword,
so you can use "foreach" for readability or "for" for brevity.
</quote>

Also test the code on a BSD system:

<quote source="ps(1)">
-C Change the way the cpu percentage is calculated by using a
``raw'' cpu calculation that ignores ``resident'' time
(this normally has no effect).
</quote>
 
A

andreas

Am Wed, 01 Nov 2006 23:57:14 +0100 schrieb Dr.Ruud:

perllexwarn
perlsub (look for "Private Variables" or "lexical")

i did the following: cat $(locate *.pod) | pod2text > perldocs.txt

this doc contanis 684 individual documents, 227818 lines of text and
10.745.665 characters - larger than twice the size of a bible! The
advantage is, one can grep anything out of a single doc. (for 'locate' one
needs the 'findutils' installed.)

thanks!

-andreas
 
A

andreas

Am Wed, 01 Nov 2006 13:35:16 -0600 schrieb Tad McClellan:
Short version:

Because they catch many common programmer mistakes, such as typos.

Yes, I'm aware of this, but preferred the shorter form -w simply because I
have to write less. In the meantime I read about the additional
features of using the pragmas 'use warnings', 'use strict' to give more
control about 'what' warning is active and where (scope) it is active. The
pragmas can be switched on an off in an individual block of code - the
command line -w applies to the whole script.

All this has to do with the perl version in use. The new pragmas seem to
start in perl 5.6. -w seems to be more compatible for older versions.
Now I hope at least 50% I have written is true ;-)

-andreas
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top