Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re^3: Construct command portable way

by ikegami (Patriarch)
on May 07, 2009 at 10:26 UTC ( [id://762556]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Construct command portable way
in thread Construct command portable way

On Windows, system(@ARGS) is system("@ARGS"), so you need to take proper care of quoting.

No it's not, so no you don't.

>perl -e"@cmd = ('perl', '-le print for @ARGV', 'foo', 'bar'); system +@cmd;" foo bar >perl -e"@cmd = ('perl', '-le print for @ARGV', 'foo bar'); system @cm +d;" foo bar

The Windows command line cannot handle some characters. You need to verify for their presence, but you won't be able to quote them.

Of course it would be nice if Win32 system() knew when to add double quotes around strings...

ActivePerl does since 5.6.1. Can't verify Perl in general.

Replies are listed 'Best First'.
Re^4: Construct command portable way
by Corion (Patriarch) on May 07, 2009 at 10:46 UTC

    This is most weird. In your case, with the hard-coded perl, it works as expected (5.8.3 here). And the following fails, as supported by your assertion:

    > perl -e"@cmd = ('perl ', '-le print for @ARGV', 'foo bar'); system @ +cmd" Der Befehl ""perl "" ist entweder falsch geschrieben oder konnte nicht gefunden werden.

    But the following does not fail:

    >perl -le "print $^X;@cmd = ($^X.' ', '-le print for @ARGV', 'foo bar' +); system @cmd" C:\Programme\Perl\bin\perl.exe foo bar

    So my guess is that $cmd[0] is inspected for whitespace or quotes, and if it contains either, an intermediate shell is invoked. Which is just a horrible kludge, especially when most programs live (under some languages) under C:\Program Files\, which already contains whitespace. And there, quoting becomes necessary:

    >perl -le "@cmd = (chr(34).$^X.' '.chr(34).' -le print+1 for @ARGV', ' +foo bar'); system @cmd" 1

    It fails (properly) when the first parameter does not start with quotes, again:

    >perl -le "@cmd = ($^X.' -le print+1 for @ARGV', 'foo bar'); system @c +md" Der Befehl ""C:\Programme\Perl\bin\perl.exe -le print+1 for @ARGV"" is +t entweder falsch geschrieben oder konnte nicht gefunden werden.

      So my guess is that $cmd[0] is inspected for whitespace or quotes, and if it contains either, an intermediate shell is invoked.

      That doesn't explain the difference at all. Both 'perl ' and $^X.' ' contain a space.

      And there, quoting becomes necessary:

      Not at all. You're mixing the single and multi-arg form for system. Quoting is not the bug. (It shouldn't work with quoting either.)

      In IPC::Exe, I do the following:
      # non-Unix: escape command so that it feels Unix-like my @cmd = $non_unix ? map { (my $x = $_) =~ s/(\\"|")/$1 eq '"' ? '\\"' : '\\\\\\"'/ge; qq("$x"); } @_ : @_;

      before exec { $cmd[0] } @cmd; (See the quoting: test in t/02_IPC-Exe.t)

      This helps to get around most of the quoting issues under Win32.

        This thread about quoting issues reminds me why I use perl (mainly for direct command line use) instead of sed for I, well, rather not deal with quoting issues (on a Unix-like system in bourne like (z)shell).

        My impending doom awaits on the other side.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://762556]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2024-03-28 17:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found