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

Can anyone explain what is doing the wild card expansion in this?

c:\test>perl -le"system 'echo junk*'" junk junk-nt junk.junk junk01.pl junk02.pl junk1 junk2 junk3 junk4 jun +ks1 junks2 junks3

If I change the command to something other than 'echo', it doesn't happen:

c:\test>perl -le"system 'type junk*'" junk* not found

And 'echo' doesn't expand wildcards natively:

c:\test>echo * *

Hence a tentative conclusion that system is doing this?

Does this happen on other, non win systems? Is it documented anywhere?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
RIP an inspiration; A true Folk's Guy

Replies are listed 'Best First'.
Re: system and wildcard expansion?
by rovf (Priest) on Nov 11, 2010 at 14:20 UTC
    Looks as if not the CMD.EXE internal command "ECHO" is executed, but an executable called echo.exe (or something like this), which is found in your path.

    -- 
    Ronald Fischer <ynnor@mm.st>
      Looks as if not the CMD.EXE internal command "ECHO" is executed, but an executable called echo.exe

      Indeed, thanks.

      It seems that system goes off searching the path for an executable with the name "echo.exe" instead of invoking the shell built in, and happens to find one that does wildcard expansion.

      I always though that if you supplied a single string argument system invoked the shell and allowed it to perform the command resolution--which would mean that it would invoke the shell built-in in preference to searching the path.

      It turns out that (on windows) it only does that if it "detects shell meta chars"--which it seems does not include * or \ or ^, as I would have assumed. Only '<', '>', '|' and '%'. Not even '&' or '&&' or '||' etc. Some attempt at *nix compatibility I think.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        It turns out that (on windows) it only does that if it "detects shell meta chars"
        From system:

        If there is only one scalar argument, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is "/bin/sh -c" on Unix platforms, but varies on other platforms). If there are no shell metacharacters in the argument, it is split into words and passed directly to "execvp", which is more efficient.

        Hence, nothing Windows-specific going on in this respect (except that the set of metacharacters differs between Windows and *nix).
        -- 
        Ronald Fischer <ynnor@mm.st>

      If it was Unix, I would try system 'which echo' to determine which binary was being run. Is there a Windows equiv?

      As Occam said: Entia non sunt multiplicanda praeter necessitatem.

        I think there is, but there's also a perl equiv:

        perl -MFile::Which -le 'print "$_: ", which $_ for @ARGV' echo
        Of course, I'm assuming you have File::Which installed :-)

        If it was Unix, I would...
        If it was Unix, I would run strace/truss/tusc, and I would know within seconds what exactly is being called with which parameters. But heh, this isn't...
Re: system and wildcard expansion?
by Corion (Patriarch) on Nov 11, 2010 at 13:17 UTC

    This is weird, because for me on ActiveState 820 (5.8.8+) with cmd.exe it works just the other way around:

    Q:\>perl -wle "system 'echo *.pl'" *.pl Q:\>perl -wle "system 'echo *'" * Q:\>perl -wle "system 'echo *.*'" *.* Q:\>perl -wle "system 'type *.pl'" lcfget.pl #!/usr/bin/perl -w use strict; use Getopt::Long; ...

    If you have cmd.exe as your shell, glob expansion should not happen, because cmd.exe does not glob. Also, (the string form of) system looks for "shell metacharacters" and if so (and on Windows, always to nearly always) invokes the shell if these are found.

    So, unless $ENV{PERL5OPT} is loading weird modules or you don't have cmd.exe as the default shell, what you see shouldn't happen (on Windows). If it is none of the above , then I would call that a regression in Perl, as especially on Windows, system() is (almost) always system(STRING) and there is no sane way for Perl to decide whether it should glob-expand parameters or not.

      as to other systems - SunOS srv13 5.9 Generic_122300-44 sun4u sparc SUNW,Sun-Fire with Perl v5.8.4 has the following results: echo

      perl -le"system 'echo *'" argtest.c bool.pl cool_fmt_tool.pl debugtst.c regexstuff regexstuff.c +regexstuff.i testx.pl useful_stuff.c

      and type (which is a bit different in unix 8^):

      perl -le"system 'type *'" argtest.c not found bool.pl not found cool_fmt_tool.pl not found debugtst.c not found regexstuff not found regexstuff.c not found regexstuff.i not found testx.pl not found useful_stuff.c not found

      I would suspect a pathing issue with somthing unixy in the path on one of my windows boxes. I have a Mac and a Win7 and a WinXP box at home and will see what they do .. now I am curious

      Misha/Michael - Russian student, grognard, bemused observer of humanity and self professed programmer with delusions of relevance

        Yes - rofv's reply is likely spot on. A unixish echo.exe in the path that does the command-line globbing itself would explain what happens.

Re: system and wildcard expansion?
by roboticus (Chancellor) on Nov 11, 2010 at 12:23 UTC

    BrowserUk:

    If I understand it correctly, it's the shell that's doing the expansion for you. I suspect that system is treating the asterisk as a shell metacharacter (as described in perldoc -f system), or perhaps it's just being a bit too 'helpful' and noticing that the command is 'echo' which is a built-in command of the shell, rather than a standalone program in Windows (last time I checked).

    Update: On second thought, I recall in the bad old days that DOS programs had to do the globbing themselves, and it was built into many C libraries into the startup code to simplify applications. Perhaps system is carrying this bodge forward?

    ...roboticus

Re: system and wildcard expansion?
by samarzone (Pilgrim) on Nov 11, 2010 at 12:34 UTC

    echo and its argument junk* are written inside single quote, so I don't think interpolation can take place inside perl. The command and its arguments are passed as it is and it is the shell who must be interpreting the '*'

    Try to run commands echo junk* and type junk* on the shell from the same directory and you'll notice the difference. Sorry. Incorrect explanation. You've already done that.

      samarzone:

      Nice try, but single quotes have nothing to do with it here: There's nothing to interpolate in the string.

      ...roboticus

Re: system and wildcard expansion?
by JavaFan (Canon) on Nov 11, 2010 at 14:36 UTC
    Hence a tentative conclusion that system is doing this?
    How did you arrive at that conclusion, given that you have two examples using system, one of them showing signs of expansion, the other doesn't? I would think that the non-expansion of perl -le"system 'type junk*'" to be a sign system doesn't do expansion.
    And 'echo' doesn't expand wildcards natively:
    c:\test>echo * *
    If your Windows shell is like many modern Unix shells, that will actually be handled internally by the shell, while the perl -le"system 'echo junk*'" actually calls a separate program.
Re: system and wildcard expansion?
by Anonymous Monk on Nov 12, 2010 at 01:36 UTC

      Indeed, when I do the same, things behave as expected:

      c:\>cd Perl64\bin c:\Perl64\bin>ren echo.exe gecho.exe c:\Perl64\bin>cd \test c:\test>perl -e"system 'echo junk*'" junk*

      Many thanks.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.