in reply to doublequoted commands inside backticks on windows, perl 5.6

Hi

The problem is a conflict between your older version of Perl and the cmd shell used to execute backticks.

When the backtick is used on windows, Perl constructs the command line and executes on the system with "cmd /x/c" by default (at least on builds before AS638; after, the /d flag was added. ).

cmd has some strange quoting behaviour. From the help cmd /?

If /C or /K is specified, then the remainder of the command line after the switch is processed as a command line, where the following logic is used to process quote (") characters:
  1. If all of the following conditions are met, then quote characters on the command line are preserved:
    1. no /S switch
    2. exactly two quote characters
    3. no special characters between the two quote characters, where special is one of: &<>()@^|
    4. there are one or more whitespace characters between the the two quote characters
    5. the string between the two quote characters is the name of an executable file.
  2. Otherwise, old behavior is to see if the first character is a quote character and if so, strip the leading character and remove the last quote character on the command line, preserving any text after the last quote character.
You are seeing the effects of the second point.

This doesn't occur in later builds of win perl, as the coders found this problem.

from the win32.c file:

/* The NT cmd.exe shell has the following peculiarity that needs + to be * worked around. It strips a leading and trailing dquote when +any * of the following is true: * 1. the /S switch was used * 2. there are more than two dquotes * 3. there is a special character from this set: &<>()@^| * 4. no whitespace characters within the two dquotes * 5. string between two dquotes isn't an executable file * To work around this, we always add a leading and trailing dqu +ote * to the string, if the first argument is either "cmd.exe" or " +cmd", * and there were at least two or more arguments passed to cmd.e +xe * (not including switches). * XXX the above rules (from "cmd /?") don't seem to be applied * always, making for the convolutions below :-( */
From the 638 diff file:

[ 12747] By: gsar on 2001/10/28 18 +:33:23 Log: finishing touches to system() fixes on windows: * detect cmd shell correctly even if it had full path i +n it * more quoting needed for single-arg system if the argu +ment really had multiple quoted arguments within it * be smarter about not calling the shell when the execu +table has spaces, but otherwise does not need shell involveme +nt * add a testsuite (windows-specific currently)
So if you run under 5.6.1 638, as ikegami did, you get the correct behaviour. See these tests.

test.pl. Calls another perl script to echo back the arguments, with your args

my $cmd="\"C:\\progra~1\\accessories\\echo_arg.pl\" -fmt \"%[owner]p\ +" vob:."; print "$cmd\n"; print `$cmd`;
Test with 5.6.1 AS635

>perl test.pl "C:\progra~1\accessories\echo_arg.pl" -fmt "%[owner]p" vob:. C:\progra~1\accessories\echo_arg.pl -fmt %[owner]p vob:.
Test with 5.6.0 AS623

>C:\progra~1\perl560_623\bin\perl test.pl "C:\progra~1\accessories\echo_arg.pl" -fmt "%[owner]p" vob:. 'C:\progra~1\accessories\echo_arg.pl" -fmt "%[owner]p' is not recogni +zed as an internal or external command, operable program or batch fil +e.
Your double-double quoting appears to be the only workaround. That is in effect what the C code does now.

- jim