Athanasius has asked for the wisdom of the Perl Monks concerning the following question:

I’m on Windows 8.1, 64-bit, using a standard DOS command-prompt (i.e., cmd.exe):

17:27 >cmd.exe
Microsoft Windows [Version 6.3.9600]

17:27 >
[download]

In Perl, I can pass an asterisk (star character, *) on the command-line with no problem:

17:27 >perl -wE "say join ' ', @ARGV;" abc * def
abc * def

17:29 >
[download]

However, in Raku it gets expanded into a list of the files in the current directory:

17:29 >raku -e "say @*ARGS.join: ' ';" abc * def
abc ch-1.pl ch-1.raku ch-2.pl ch-2.raku Session.xml test.bat def

17:43 >
[download]

So I have two questions:

1. Is this documented? I’ve looked at https://docs.raku.org/language/create-cli but didn’t find the explanation I was looking for.
2. Is there a way to turn off wildcard expansion when inputting * on the command line? I’ve tried prepending ^ and \, and putting the star into single and double quotes, but without success. Ideally, I’d like to change some setting in the Raku script itself, if there’s such an option.

For the record:

• Perl: Strawberry Perl 5.32.0 64bit
• Raku: Rakudo version 2020.05.1 built on MoarVM version 2020.05 implementing Raku 6.d

Thanks,

 Athanasius <°(((>< contra mundum Iustus alius egestas vitae, eros Piratica,

Replies are listed 'Best First'.
Re: [Raku] Asterisk on DOS command line
by LanX (Sage) on Feb 10, 2021 at 14:39 UTC
It always bothered me that cmd-shell doesn't do a glob expansion of * like the bash does. (I.e. before passing the parameters, e.g. try echo * )

My guess is that Raku is compensating this to allow more symmetry between the platforms.

> I’ve tried prepending ^ and \, and putting the star into single and double quotes, but without success.

Looks like a bug to me.

HTH!

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

Re: [Raku] Asterisk on DOS command line
by jcb (Parson) on Feb 11, 2021 at 02:52 UTC

The problem here is Windows. Unlike POSIX systems, which pass an argument vector containing strings, WinDOS passes only a "command tail" string into the new process. The C runtime library then interprets that string to find argc and build argv to pass to main.

Wildcard expansion (or lack thereof) on Windows is therefore a function of the runtime libraries perl and raku are linked against, but the CMD shell apparently does strip some quotes, just because it was not confusing enough. Try "'*'", which also may or may not work.

Hello jcb,

very interesting indeed! This is the first time I read something like this on the argument and you will pardon my ignorance on the whole matter.

> The C runtime library then interprets that string to find argc and build argv to pass to main

Given your precious hint I discovered perlwin32#Using-perl-from-the-command-line documentation. But let me see if I understood it right.

The above document says:

> It is particularly important to note that neither the shell nor the C runtime do any wildcard expansions of command-line arguments

and the above sounds different from your statement "Wildcard expansion ... is therefore a function of the runtime libraries perl and raku are linked against".

But what you said seems confirmed by some experiment: yesterday I chatted a bit on the #raku channel on irc and someone said they noticed opposed behaviour on windows, with and without expansion, probably due to different build of the raku itself, rakubrew iirc.

So the above document (related to perl but I suppose is valid for raku too) seems to be incorrect in the sense that sometimes perl or raku can be built using a C runtime library that effectively does the expansion? Can be this the case of the OP?

If the above is true then can be perl built on windows using a C runtime library that is able to expand the * char as done by more smart shells? This would be a nice improvement.

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
> But the CMD shell apparently does strip some quotes

I don't have Raku so I tested against Perl.

Looks like only doublequotes are stripped if not escaped.

D:\tmp\pm>perl -e"print @ARGV" *
*
D:\tmp\pm>perl -e"print @ARGV" '*'
'*'
D:\tmp\pm>perl -e"print @ARGV" "'*'"
'*'
D:\tmp\pm>perl -e"print @ARGV" "*"
*
D:\tmp\pm>perl -e"print @ARGV" \*
\*
D:\tmp\pm>perl -e"print @ARGV" \"*\"
"*"
D:\tmp\pm>
[download]

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

Re: [Raku] Asterisk on DOS command line
by Athanasius (Archbishop) on Feb 11, 2021 at 12:10 UTC

Thanks LanX, jcb, and Discipulus for a useful discussion. I also found:

which I’ve only skimmed, but which appear to show that this is a known issue in Raku: I think it’s still to be resolved.

Cheers,

 Athanasius <°(((>< contra mundum Iustus alius egestas vitae, eros Piratica,

Sorry, but the best answer seems to be: avoid cmd.exe as a shell.

Raku seems to attempt to compensate the shortcomings of cmd, but this can never fully succeed, since cmd does it's own expansions

for instance environment vars inside % are expanded, no matter if quoted or not

D:\tmp\pm>perl -e"print '%OS%'"
Windows_NT
D:\tmp\pm>
[download]

And even if Raku succeeds in better compensating cmd-shell, I sincerely hope this is not globally so on Win and deactivated for other SHELLs.

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

Re: [Raku] Asterisk on DOS command line
by sortiz (Initiate) on Feb 11, 2021 at 18:51 UTC

In Windows 10 and using rakubrew I found the behavior indeed depends of the build environment used.

With a raku built with MS tools the arguments remains unexpanded as expected:

C:\moar-2020.05.1\bin>raku -e "say @*ARGS.join: ' ';" abc * def
abc * def

C:\moar-2020.05.1\bin>raku -e "say $*VM.config<cc ldlibs>" (cl shell32.lib ws2_32.lib mswsock.lib rpcrt4.lib advapi32.lib psapi. +lib iphlpapi.lib userenv.lib user32.lib) [download] When built with mingw tools (from Strawberry perl) the resulting raku expands: C:\moar-2020.05\install\bin>raku -e "say @*ARGS.join: ' ';" abc * def abc libmoar.dll.a moar.dll moar.exe nqp-m.exe nqp.exe perl6-debug-m.ex +e perl6-debug.exe perl6-m.exe perl6.exe raku-debug.exe raku.exe rakud +o-debug-m.exe rakudo-debug.exe rakudo-m.exe rakudo.exe def C:\moar-2020.05\install\bin>raku -e "say$*VM.config<cc ldlibs>"
(gcc  -lshell32 -lws2_32 -lmswsock -lrpcrt4 -ladvapi32 -lpsapi -liphlp
+api -luserenv -luser32)
[download]

As the linked libraries are the same, I can only think in some differences in the startup code injected by the build environment.

You are correct; the C runtime startup code is responsible for preparing the arguments to main on Windows. Native Windows programs do not use main as their entry point.

Most likely, the mingw startup code expands globs because GNU programs expect the shell invoking them to have already done that. If the MinGW C startup code did not do this, most GNU programs would not support filename globs on Windows.

There should be an option to specify whether or not to expand globs in argv when linking a MinGW program, since most programs need that, but a few do not. If there is no such option currently, that is arguably a bug in MinGW.

For MinGW64's gcc, the included with Strawberry perl, I found that adding to the linker one of the included crt files CRT_glob.o or CRT_noglob.o does the trick. Choice your poison.