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

I am trying to run an external command on Windows using the backtick operator. The OS has 8.3 naming convention enabled and the to the external command has some special characters in it. The problem is that when I send the command without any arguments, it fails with the error "The system cannot find the path specified.". But when I provide an argument, it succeeds. Am I missing something here? e.g.
$path = "\"" . Win32::GetShortPathName($home) . "\"\\$cmd"; my $op = `$path`; <== Fails my $op = `$path -v`; <== succeeds.
Thanks in adv.

Replies are listed 'Best First'.
Re: perl windows backtick problem
by Marshall (Canon) on Sep 21, 2011 at 16:17 UTC
    Geez. I am having trouble understanding your core problem.

    This 8.3 naming stuff is "bad juju". Using WinXP or later, there is no reason to work with an 8.3 name. The 8.3 name for a given file varies depending upon other similar files which are in that directory and would "hash" to the same 8.3 name! There is no fixed 8.3 name for a Windows NTFS file name.

    Also, with Win XP (or greater) in most (not all) cases, you can use "/" instead of "\", so this confusing "\\" stuff is not necessary.

    What does this mean: the "______" to the external command has some special characters in it.?

    Update:
    I ran some quick tests...

    C:\PROJECTS>dir //$home Invalid switch - "/". C:\PROJECTS>dir /$home Invalid switch - "$home". C:\PROJECTS>dir \\$home The filename, directory name, or volume label syntax is incorrect. C:\PROJECTS>dir \$home Volume in drive C is Main-Max Volume Serial Number is 89D1-9F45 Directory of C:\ File Not Found C:\PROJECTS>dir "\$home" Volume in drive C is Main-Max Volume Serial Number is 89D1-9F45 Directory of C:\ File Not Found C:\PROJECTS>dir c:\ Volume in drive C is Main-Max Volume Serial Number is 89D1-9F45 Directory of c:\ MANY..MANY files....meaning that windows had trouble with: dir "\$home +"
    It is important that you show us exactly the code that you are using. Try again and please pay attention to what I said about 8.3 names -> don't use them! Somewhere I have the algorithm for generating 8.3 names, but it might take me a couple of hours to find it. But this one of those deals where if you have all of the information to generate the 8.3 name, then you don't need the 8.3 name! Use the NTFS 32 character name!

      I ran some quick tests...

      All you've demonstrated is that the cmd.exe built-in command "dir" uses / for processing arguments, as documented

      $ "C:/MinGW/msys/1.0/bin/dir.EXE" asdf "C:/MinGW/msys/1.0/bin/dir.EXE": asdf: No such file or directory $ "C:\MinGW/msys/1.0/bin\dir.EXE" asdf "C:/MinGW/msys/1.0/bin/dir.EXE": asdf: No such file or directory $ C:\MinGW/msys/1.0/bin\dir.EXE asdf /usr/bin/dir: asdf: No such file or directory $ C:\MinGW/msys/1.0/bin\dir.EXE\$HOME asdf The directory name is invalid. $ C:\MinGW/msys/1.0/bin\dir.EXE\blah.exe The directory name is invalid.

      This 8.3 naming stuff is "bad juju".

      Yup, that is why there is NtfsDisable8dot3NameCreation, but it does have benefits

      8.3 saves you the trouble of quoting paths in the shell, say for batch files and the like

      8.3 spares you the headache of dealing with broken programs that don't quote paths they give to the shell, like legacy applications

      8.3 spares you the headache of dealing with broken programs that split on whitespace

        But the BIG disadvantage is that there is no 1->1 mapping between the NTFS name and the 8.3 name! It is not possible to uniquely map a 32 character name into an 8 character name! ABCDEFGHIJ.EXE will have a different 8.3 name on different systems depending upon what other files are in the directory.

        Let's see what the OP (original poster) has to say. I am curious as to the application...

Re: perl windows backtick problem
by Anonymous Monk on Sep 21, 2011 at 16:07 UTC
    GIGO :) Never seen a program or path that begins and ends with quotes as part of it, or quotes followed by a backslash
    $nonsense = q{"C:\PROGRA~1\MOZILL~1\firefox.exe"\ }; qx{ $nonsense }; __END__ '"C:\PROGRA~1\MOZILL~1\firefox.exe"\' is not recognized as an internal + or external command, operable program or batch file.
Re: perl windows backtick problem
by Kc12349 (Monk) on Sep 21, 2011 at 16:05 UTC

    Please supply us with some code (wrapped in <c> tags) we can run to reproduce what you are seeing.

Re: perl windows backtick problem
by Anonymous Monk on Sep 22, 2011 at 07:40 UTC
    Thanks guys for the quick replies. And apologies for making it too general. Here is the code:
    require Win32; Win32->import; my $patharg = $ARGV[0]; print "ARGV: [$patharg]\n"; $path = "\"" . Win32::GetShortPathName($patharg) . "\""; print "patharg: [$patharg]\n"; print "path: [$path]\n"; my $cmd = "$path\\disc"; print "Issuing cmd: [$cmd]\n"; my $op = `$cmd`; my $ret = $?; print "ret: [$ret], op: [$op]\n"; $cmd = "$path\\disc -v"; print "Issuing cmd: [$cmd]\n"; $op = `$cmd`; $ret = $?; print "ret: [$ret], op: [$op]\n" ####################
    Output:
    C:\Users\Administrator.ZEN>perl test.pl "C:\Program Files\GFN%$^#\CLI\ +bin" ARGV: [C:\Program Files\GFN%$^#\CLI\bin] patharg: [C:\Program Files\GFN%$^#\CLI\bin] path: ["C:\PROGRA~1\GFN%$^#\CLI\bin"] Issuing cmd: ["C:\PROGRA~1\GFN%$^#\CLI\bin"\disc] The system cannot find the path specified. ret: [256], op: [] Issuing cmd: ["C:\PROGRA~1\GFN%$^#\CLI\bin"\disc -v] ret: [0], op: [ Discovery Version: 7.2.10.0 <snip> ]
    If I maually run the command without any args, it runs fine:
    C:\Users\Administrator.ZEN>"C:\Program Files\GFN%$^#\CLI\bin"\disc Discovery Version: 7.2.10.0
    I have to qualify the script with paths containing such special characters.