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

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.

Replies are listed 'Best First'.
Re^5: Construct command portable way
by ikegami (Patriarch) on May 07, 2009 at 11:12 UTC

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

Re^5: Construct command portable way
by repellent (Priest) on May 07, 2009 at 20:32 UTC
    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.