killing processes using perl (artsd)

Discussion in 'Perl Misc' started by andreas, Oct 31, 2006.

  1. andreas

    andreas Guest

    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
    andreas, Oct 31, 2006
    #1
    1. Advertising

  2. On 10/31/2006 12:37 PM, andreas wrote:
    > 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.

    --
    Mumia W. (reading news), Nov 1, 2006
    #2
    1. Advertising

  3. On 10/31/2006 09:58 PM, Mumia W. (reading news) wrote:
    > On 10/31/2006 12:37 PM, andreas wrote:
    >> 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);


    --
    Mumia W. (reading news), Nov 1, 2006
    #3
  4. andreas

    Dr.Ruud Guest

    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 ;

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Nov 1, 2006
    #4
  5. andreas

    andreas Guest

    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
    andreas, Nov 1, 2006
    #5
  6. andreas

    andreas Guest

    Am Wed, 01 Nov 2006 08:44:04 +0100 schrieb 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 ;


    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.
    >
    >
    >> # 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 ;


    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
    andreas, Nov 1, 2006
    #6
  7. andreas

    andreas Guest

    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
    andreas, Nov 1, 2006
    #7
  8. andreas <andreas./@> wrote:
    > Am Wed, 01 Nov 2006 08:44:04 +0100 schrieb Dr.Ruud:


    >> Remove the -w, and add:
    >>
    >> use warnings ;
    >> use strict ;

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



    Short version:

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


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Nov 1, 2006
    #8
  9. andreas

    Dr.Ruud Guest

    andreas schreef:
    > Dr.Ruud:


    >> print "kill '$_'\t?\n" for @pids ;

    >
    > 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>

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Nov 1, 2006
    #9
  10. andreas

    Dr.Ruud Guest

    andreas schreef:
    > Dr.Ruud:


    >> use warnings ;
    >> use strict ;

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


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

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Nov 1, 2006
    #10
  11. andreas

    andreas Guest

    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
    andreas, Nov 3, 2006
    #11
  12. andreas

    andreas Guest

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

    > andreas <andreas./@> wrote:
    >> Am Wed, 01 Nov 2006 08:44:04 +0100 schrieb Dr.Ruud:

    >
    >>> Remove the -w, and add:
    >>>
    >>> use warnings ;
    >>> use strict ;

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

    >
    >
    > 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
    andreas, Nov 3, 2006
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stu
    Replies:
    2
    Views:
    470
  2. bugbear
    Replies:
    1
    Views:
    1,031
    bugbear
    Nov 4, 2005
  3. hepp

    Killing processes

    hepp, Aug 30, 2004, in forum: C++
    Replies:
    1
    Views:
    418
    Victor Bazarov
    Aug 30, 2004
  4. Andrei

    killing processes on win xp

    Andrei, Feb 11, 2004, in forum: Python
    Replies:
    1
    Views:
    540
    Yen-Ting Chen
    Feb 13, 2004
  5. x1
    Replies:
    15
    Views:
    265
Loading...

Share This Page