in reply to (Windows) verbatim command line arguments inside Perl script

The quoting gets lost when the shell parses the command line arguments. Your @ARGV has three elements, as you can check with perl -E"$,=':';say @ARGV" "1 2" "3" 4, which gives 1 2:3:4.

The echo command is exempt from this parsing: it is a builtin of cmd.exe.

You can accept the list from @ARGV and re-establish a "correct" quoting by passing the list to the appropriate function of Win32::ShellQuote] (or ShellQuote::Any, if portability matters). The documentation of Win32::ShellQuote comes with a warning, though:

Perl will try to detect if you need the shell by detecting shell metacharacters. The routine that checks that uses different quoting rules from both cmd.exe and the native Win32 parsing. Extra work must therefore be done to protect against this autodetection.
Your mileage will vary :)

Replies are listed 'Best First'.
Re^2: (Windows) verbatim command line arguments inside Perl script
by haukex (Archbishop) on Apr 16, 2021 at 14:49 UTC
    The quoting gets lost when the shell parses the command line arguments.

    I'm not an expert, but I thought that part of the issue is that on Windows, that's actually not what happens? I'm looking at Re^3: Perl Rename.

    Update: Unless with that sentence you were referring to *NIX systems, in which case you're right of course.

      Ah, you're correct, of course. That was my initial thought (because that's how it is done in Linux), but then I read the docs of Win32::ShellQuote which tells a different story:

      Windows passes its arguments as a single string instead of an array as other platforms do.
      - and then I copied a presumably relevant part of that docs into my reply without correcting the first sentence.

      BTW: Windows has other ... interesting ... challenges when parsing command line arguments. Try this:

      perl -E "say @ARGV" €
Re^2: (Windows) verbatim command line arguments inside Perl script
by LanX (Saint) on Apr 16, 2021 at 14:53 UTC
    Thanks, I was hoping for such modules ... :)

    ... but

    > The quoting gets lost when the shell parses the command line arguments.

    AFAIK that's true on Linux but not on Win

    quoting Win32::ShellQuote

    > Windows passes its arguments as a single string instead of an array as other platforms do. In almost all cases, the standard Win32 CommandLineToArgvW function is used to parse this string

    So the win-built of Perl is deconstructing the input-line into @ARGV. (we had a similar discussion not long ago)

    Hence it's not unthinkable to have a special var akin to %* in Perl to access that original line.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      Yeah, I noticed (too late) that I failed to correct that sentence after reading the docs of Win32::ShellQuote. Sorry.

      If I understand correctly, it is even more convoluted than that: cmd.exe does perform some substitutions, so there really is no way to get the exact command line, even though Windows provides a "command tail" instead of an argument vector. The Windows build of perl does nothing special here — the C runtime library startup code parses the command tail and builds an argument vector that perl then packages into @ARGV.

        > cmd.exe does perform some substitutions,

        If you are referring to %variables% , that's fine.

        I only need to be able to reproduce the exact call inside a Perl wrapper.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery