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

Dear Monks

I'm trying to use Perl's glob against a Windows network (i.e. UNC) path, where the first part of that path is held in a variable. I want to cater for cases where the part of the path held in the variable may contain whitespace, so I add the protection of an extra layer of quotes around it:

my $dir = '//datastore/genexternal/aoi'; print glob "'$dir/*'";

This simply doesn't work: it prints nothing. I get the same results in both Strawberry Perl and Active State Perl, running on Windows XP or Windows 7. I get these results in Active State Perl 5.10.1, running on either Windows XP or Windows 7.

It also does not work if:

I get the same results if I try switching the slash characters to backslashes.

By contrast, each of the following does work:

Do you have any idea why it should fail for my UNC path?

Ed

Replies are listed 'Best First'.
Re: Whitespace protection in glob expression for Windows network paths
by toolic (Bishop) on Nov 11, 2014 at 14:35 UTC
    Maybe you'll struggle less with readdir instead of glob in this case.
      Thanks toolic for that good suggestion. That was uncharted territory for me. Just checked it out, and it seems to work very well. Bye bye glob on Windows!
Re: Whitespace protection in glob expression for Windows network paths
by RichardK (Parson) on Nov 11, 2014 at 14:59 UTC

    Does bsd_glob do any better? see File::Glob -- it doesn't split patterns on spaces, so might just give you a better result.

    The help for glob suggests a different syntax for passing variables, so you might try that too.

      Thanks RichardK for another good suggestion. I've tried this, and it also seems to do the trick nicely: minimal changes to existing code, and I can dispense with the nested quotes. The only funny was that the File::Glob in my Strawberry Perl doesn't seem to export bsd_glob, so I had to call it by its fully qualified name, but that's no hardship. The only funny is that in the version of File::Glob in Active State Perl 5.10.1, the :bsd_glob export tag isn't recognised, but the function itself is still exported: use File::Glob 'bsd_glob';.

      I see the manual page for File::Glob refers also to File::DosGlob, but I was a little too put off by the latter's manual page to take that idea any further.

      By the way, the "help for glob" to which you refer was what I was following when I first started to code this, and that's what led me into this fine mess.
Re: Whitespace protection in glob expression for Windows network paths
by SuicideJunkie (Vicar) on Nov 11, 2014 at 14:33 UTC

    Single quotes will not work (try it in a cmd window). You need to use double quotes.

    print glob "\"$dir/*\""; Should work better.

      Thanks SuicideJunkie for your amazingly quick response. But ... it doesn't work for me. I get the same results as before.

      You've prompted me to retry the whole exercise in a cmd window, and lo and behold everything works fine there. It's only when running it from a script that it fails. Very strange.

      I've since realised the different results from the script and the interactive session were because the latter was using Strawberry Perl, which doesn't have this problem. Mystery solved. Duh...!

        SuicideJunkie's reply Re: Whitespace protection in glob expression for Windows network paths "works" (on a local or mapped drive) with Win7, AS 5.018 ...

                  ... as a script:

        #!/usr/bin/perl use warnings; use strict; use 5.018; # 1106821 my @dir = @ARGV; for my $dir(@dir) { print glob "\"$dir/*\"\n"; }

                  ... and as a one-liner at the cmd prompt:

        C:\>perl -E "my $dir = \"d:\_wo\"; print glob \"$dir/*\";

        where "works" is not deprecated as a descriptor because of its failure to terminate each item with a return, tab or other spacer... but that's an issue rooted in this usage of glob.

        You're apt to learn something valuable if you'll do the necessary work to trace down and understand what went wrong with your attempt to implement the first reply.


        ++$anecdote ne $data


Re: Whitespace protection in glob expression for Windows network paths (bsd_glob)
by tye (Sage) on Nov 11, 2014 at 18:02 UTC
    use File::Glob 'bsd_glob'; my $path = "c:/Program Files"; # $path =~ s/ /[ ]/g; # Oh, not even required print $_, $/ for bsd_glob("$path/*");

    - tye        

      Thanks tye - same suggestion as RichardK's, but with nice succinct code. I've ended up adopting the bsd_glob solution in my scripts, and it works well.