Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Query on Perl system command

by Anonymous Monk
on Mar 04, 2011 at 12:26 UTC ( #891434=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have a query on perl system command. I would like to learn from perl monks how to place variables inside system command ?

In the script below, program "phylip" generates two output files and asks user to name them. I want to name the first output file as "blah.txt" and second as "blah.xls".

$filename ="blah.doc"; .... .... $filename =~ s/\.doc//; system 'echo "$filename.txt\n$filename.xls\n" | phylip';

(blah.doc is the input file, I use at the beginning of a long script)

when I run above script, "phylip" doesn't recongnize either of the filenames. Can anyone advise me, how to go about doing this ?

Comment on Query on Perl system command
Download Code
Re: Query on Perl system command
by Anonymous Monk on Mar 04, 2011 at 12:42 UTC
    Single quotes do not interpolate, you need double quotes, with alternate delimiters,
    $filename =~ s/\.doc$//; qq(echo "$filename.txt\n$filename.xls\n" | phylip ); qq~echo "$filename.txt\n$filename.xls\n" | phylip ~;
    See perlintro, perlop#Quote and Quote-like Operators
      When I modified

      system 'echo "$filename.txt\n$filename.xls\n" | phylip';

      with

      qq(echo "$filename.txt\n$filename.xls\n" | phylip );

      OR with

      qq~echo "$filename.txt\n$filename.xls\n" | phylip ~;

      I get the following error message

      "Useless use of string in void context at alignment.pl line 75."

      Any idea, why this is happening ? (I am newbie to perl)

      I appreciate your help

        I'm a newbie to your code.

        Which is / what's in "Line 75?"

      You wrote

      qq(echo "$filename.txt\n$filename.xls\n" | phylip ); qq~echo "$filename.txt\n$filename.xls\n" | phylip ~;

      Your script would have been

      system qq(echo "$filename.txt\n$filename.xls\n" | phylip ); system qq~echo "$filename.txt\n$filename.xls\n" | phylip ~;

      I made a mistake by running your script blindly, so it didn't work that time. Yes you are right, single quotes do not interpolate, I needed double quotes !

      Thank you :-)
Re: Query on Perl system command
by philipbailey (Chaplain) on Mar 04, 2011 at 12:48 UTC

    It looks like a quoting problem. It seems that you want to interpolate your variable $filename within your quoted string but interpolation does not happen within Perl's single quotes.

    There are several possibilities, but one would be to use double quotes, then escape the double quotes and "\n" you are using:

    system "echo -e \"$filename.txt\\n$filename.xls\\n\" | phylip";

    Also note that, on my system at least, I need the -e option to get backslash escapes to be interpreted.

      Thanks Philip Bailey.

      I put up a simplified script in my query, but the actual script is different. It is given below. (Description of this script is in Re^4 above)

      As suggested by you, I modified script

      system 'echo "4\n6\n3\n5\n\n1\n$filename.fsmi\n5\n$filename.phb\n111\n +1000\n4\n$filename.ph\n$filename.dst\n\n2\n" | phylip';

      with

      system "echo -e \"4\\n6\\n3\\n5\\n\\n1\\n\"$filename.fsmi\"\\n5\\n\"$f +ilename.phb\"\\n111\\n1000\\n4\\n\"$filename.ph\"\\n\"$filename.dst\" +\\n\\nx\\n\" | phylip" ;

      I did not get any error message, but, none of the choices are recognized

      I appreciate your help, thank you

        Have you also tried without the -e option?  Not all echos require that option, and in the other thread it looks like your echo doesn't.

        Another approach would be to do away with system, echo, quoting issues, etc. and use open to open a pipe to phylip, into which you then just print the required input, including newlines.  For example:

        open my $pipe, "| phylip" or die $!; print $pipe <<"EOI"; 4 6 3 5 1 $filename.fsmi 5 $filename.phb 111 1000 4 $filename.ph $filename.dst x EOI close $pipe;

        A positive side effect is that the sequence of things you have to enter becomes much better to read.

        (Note that the heredoc, as shown, is interpolating $filename (like a double-quoted string). )

Re: Query on Perl system command
by TomDLux (Vicar) on Mar 05, 2011 at 00:26 UTC

    I bet your phylip program asks the uses to type the first filename, reads the name in, asks for the second filename, etc.

    Instead, make the program read the command line arguments it is invoked with, after which you can run it as

    system( '/path/to/phylip', "$filename.txt", "$filename.xls" );

    You COULD have the program name and arguments all as one string, but then the shell is invoked to interpret things. With an array of args to system(), the program is invoked wthout involving the shell. That means you don't have to worry about the possibility of $filename having the value ';rm -rf'.

    As Occam said: Entia non sunt multiplicanda praeter necessitatem.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (18)
As of 2014-09-22 14:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (195 votes), past polls