neversaint has asked for the wisdom of the Perl Monks concerning the following question:

Dear Masters,
What's wrong with my snippet here.
my @load = `ps -ef | grep neversaint | grep 'somecmnd.exe$' | wc -l`;
It seems that Perl can't recognize the regex in the second grep. What's the correct way to do it?

---
neversaint and everlastingly indebted.......

Replies are listed 'Best First'.
Re: Quoting in Backtick
by Fletch (Bishop) on Oct 27, 2007 at 04:31 UTC

    Quoting issues in the backticks aside, it might be worth the 4 extra lines of code to simply open a pipe from ps and do the winnowing and line counting yourself in your Perl rather than piping to the external commands.

    open( my $ps_fh, "-|", "ps -ef" ) or die "Can't open pipe from ps: $!\ +n"; my $load = 0; while( <$ps_fh> ) { $load++ if /somecmnd\.exe$/; } close( $ps_fh );
Re: Quoting in Backtick
by kyle (Abbot) on Oct 27, 2007 at 03:46 UTC

    On my system, your code produces this error:

    sh: -c: line 0: unexpected EOF while looking for matching `''

    Backticks interpolate like double quotes, so you need to escape the $

    my @load = `ps -ef | grep neversaint | grep 'somecmnd.exe\$' | wc -l`;
Re: Quoting in Backtick
by GrandFather (Saint) on Oct 27, 2007 at 03:46 UTC

    You are interpolating the contents of Perl's post match special variable $' into your backticks string. Is that what you intend?


    Perl is environmentally friendly - it saves trees
Re: Quoting in Backtick
by tinita (Parson) on Oct 27, 2007 at 17:08 UTC
    programmers are just human and make mistakes. by forming a habit you can avoid making mistakes.
    in the case of doing system commands i usually do:
    my $cmd = "some command"; print "$cmd\n"; # comment out later my $res = qx{$cmd};
    so i always see first what the command will look like. in your case you would have recognized that the $' has vanished.
Re: Quoting in Backtick (readpipe)
by lodin (Hermit) on Oct 28, 2007 at 11:26 UTC

    Nowadays you can use readpipe() instead of backticks. You use readpipe() just as any other function, so you can use single quotes to avoid any interpolation.

    lodin

Re: Quoting in Backtick
by Anonymous Monk on Oct 28, 2007 at 18:53 UTC

    Are you sure that you want to invoke ps, grep and wc without a full path? This may be a security issue.

    And why do you start five processes (shell, ps, 2x grep, and wc) where one is sufficient? grep and wc can easily be done in Perl, without a new process. The shell does not have to be invoked, you can use exec "/bin/ps","-ef";. You just have to read the output from that process, see Safe Pipe Opens in perlipc, especially the "safe backtick or pipe open for read" example. Replace the while loop in the parent process with an array read plus two Perl greps, and finally use scalar @array to get the line count.