Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

spaces in grep command argument executed in backticks

by chilukuri_perl (Novice)
on Oct 22, 2009 at 05:52 UTC ( #802648=perlquestion: print w/ replies, xml ) Need Help??
chilukuri_perl has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
$module variable contains white spaces which are interprested by shell and giving the errors
$module = "xyz abc"; $pid = `ps -aef|grep "$module"|grep -v grep |cut -d ' ' -f3`; grep: can't open xyz grep: can't open abc
How can shell interpretation of white spaces can be avoided for above prupose
Thanks

Comment on spaces in grep command argument executed in backticks
Download Code
Replies are listed 'Best First'.
Re: spaces in grep command argument executed in backticks
by jwkrahn (Monsignor) on Oct 22, 2009 at 06:23 UTC
    my $module = 'xyz abc'; open my $PIPE, '-|', 'ps', '-aef' or die "Cannot open pipe from 'ps' $ +!"; my $pid; while ( <$PIPE> ) { next unless /$module/; $pid = ( split )[ 2 ]; } close $PIPE or warn $! ? "Error closing 'ps' pipe: $!" : "Exit status $? from 'ps'";
Re: spaces in grep command argument executed in backticks
by cdarke (Prior) on Oct 22, 2009 at 08:03 UTC
    The third field of ps -ef is the parent pid, did you mean that? Also, you can avoid the extra grep -v with a simple RE trick:
    $module = "xyz ab[c]"; $pid = `ps -aef|grep \"$module\"|cut -d ' ' -f3`;
    Note the [ ] around one of the characters.

    Back to perl, here is a simple one-liner (OK, three lines) which only creates one child process:
    my $module = 'xyz abc'; my @ppids = map {(split)[2]} grep /$module/,`ps -ef`; print "@ppids\n";
    If you really wanted the pid rather than the ppid then change the [2] to [1].
    Notice that I am using an array, since there might be more than one process which matches.
      my @ppids = map {(split)[2]} grep /$module/,`ps -ef`;
      my @ppids = map /$module/?(split)[2]:(), `ps -ef`;
Re: spaces in grep command argument executed in backticks
by jakobi (Pilgrim) on Oct 22, 2009 at 07:33 UTC

    For a general solution surviving not just embedded blanks, check the recent thread on use variables of system and my reply on secure use here.</p.

    Then again, you can just move the grep to perl, which takes also care of the issue and allows more powerful regexes. A perl -e "one-liner" example would be e.g.

    perl -e '$module=$ARGV[0]; @ps=`ps -eaf`; shift @ps if $ps[0]=~/^UID|^USER/; @ps=grep {/$module/} @ps; $pid=+(split / +/, $ps[0])[1]; warn "pid: $pid"; warn "multiple matches" if $#ps>0; warn @ps' urxvt

    Wasn't there a module to abstract from or at least parse ps: the ps output if rather inconsistent when comparing e.g. BSD vs SYSV vs GNU...? Just consider the PID field, which for me is the 2nd field.

    Update: stripped the and not /grep/ from the grep, claiming shell muscle memory - ps and a lone grep in one line just feel wrong. @jwkrahn thanx for spotting it!

      @ps=grep {/$module/ and not /grep/} @ps;

      Why would you try to match the string /grep/ when you are using Perl's grep function.    That makes no sense at all.

Re: spaces in grep command argument executed in backticks
by Anonymous Monk on Oct 22, 2009 at 06:12 UTC

    use single quotes

    grep \'$module\'

    or alternatively use

    $module ="'xyz abc'"

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://802648]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2015-08-04 07:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The oldest computer book still on my shelves (or on my digital media) is ...













    Results (62 votes), past polls