in reply to stat on file name containing single quotes

Exactly how are you assigning $fn.

Please post a short but complete test script that demonstrates the problem.

  • Comment on Re: stat on file name containing single quotes

Replies are listed 'Best First'.
Re^2: stat on file name containing single quotes
by stevieb (Canon) on Jul 30, 2015 at 21:32 UTC

    I was just going to ask that after I quickly tested the following successfully on Windows.

    use strict; use warnings; my $fn = "this 'is' a text file.txt"; my @a = stat $fn; print "$_\n" for @a;

      Yes, that works, but when you start adding the full path which also includes spaces, it fails.

      The issue is with getting the quoting and escaping set correctly for the shell.

      c:\test>dir "C:\Music\Ray LaMontagne" Volume in drive C has no label. Volume Serial Number is 4CD3-F30A Directory of C:\Music\Ray LaMontagne 07/30/2015 02:31 PM <DIR> . 07/30/2015 02:31 PM <DIR> .. 07/30/2015 02:31 PM 0 2010 - God Willin' & The Creek +Don't Rise.txt 1 File(s) 0 bytes 2 Dir(s) 938,700,210,176 bytes free c:\test>type Perl-1.pl #!/usr/bin/perl use 5.010; use strict; use warnings; use Data::Dumper; # I created this full path for the test my $fn = q(C:\Music\Ray LaMontagne\2010 - God Willin' & The Creek Don' +t Rise); print $fn, $/; #my $fn = "this 'is' a text file.txt"; my @s = stat $fn; print Dumper \@s; c:\test>Perl-1.pl C:\Music\Ray LaMontagne\2010 - God Willin' & The Creek Don't Rise $VAR1 = [];

      I've delt with this issue before and always need to run a bunch of tests to get the quoting/escaping correct.

Re^2: stat on file name containing single quotes
by perlpipe (Acolyte) on Jul 31, 2015 at 14:41 UTC

    The line is in fact read from a text file. Here is some simplified code that reads from a file containing only the one line I am talking about here.

    use 5.12.0; use strict; use warnings; use Carp; open IN,"<DirList.txt"; my $fn=<IN>; chomp $fn; say $fn; my @st=stat $fn; if (@st) { say "Array defined"; } else { say "Array undefined"; }

    The result is:

    E:\Music\Ray LaMontagne\2010 - God Willin' & The Creek Don't Rise Array undefined
      Note that the "chomp" and the "say" don't seem to have a problem with the variable $fn containing a string that has single quotes and backslashes in it. So I was expecting "stat" to not have a problem. Obviously I was wrong.

        I had no problem using stat on a file path containing backslashes and apostrophes. (Just to be clear, that doesn't mean that those characters aren't indeed the problem in your environment.)

        One possible explanation for your problem above would be a simple "\r" at the end of the string after chomp was called. Any number of other "invisible" characters could also be to blame. At least output the length of the string as well. Adding surrounding punctuation to the output can help for some "invisible" characters. Using something like Data::Dumper (if you set the option to use double quotes instead of single quotes) or the Perl debugger (see the "x" command) can make such problems obvious.

        And, yes, even if you are using a native Windows build of Perl that by default replaces "\r\n" with "\n" when reading, it would replace "\r\r\n" (for example) with "\r\n" and chomp would replace that with just "\r", which would cause the behavior you showed.

        - tye        

      Further testing indicates that we are getting side tracked by the single quote issue. That is if we change the input file so it specifies a file or directory name that contains extended ascii as in an accented e (0x82) then we get the same result with the stat function. Windows accepts these name. stat does not. The name I tested with came from my Adobe Acrobat installation in C:\Program Files (x86).

      Here is the modified program run against an updated input file.

      use 5.12.0; use strict; use warnings; use Carp; open IN,"<DirList2.txt"; my $fn=<IN>; chomp $fn; my @st=stat $fn; if (@st) { say "Array defined"; } else { say "Array undefined"; }

      The input was:

      C:\Program Files (x86)\Adobe\Acrobat 10.0\Acrobat\Sequences\FRA\Cr0xc20x82er des fichiers PDF accessibles.sequ

      The output was:

      Array undefined

        Yeah, that can happen.

        Win32 supports single-byte-character API calls ("A") or UTF-16 API calls (called "UNICODE" or "W"). When using "A" calls, you can only represent characters in your defined "code page" (which then get converted to UTF-16 which is what is used by the underlying OS code).

        So either change your code page or use the "W" APIs. You'll have to do some searching to figure out what is the current state of getting access to the "W" APIs from Perl. I've seen several paths for doing such with different trade-offs but it has been so long since I've looked at that so I won't throw out my faded memory of out-dated info.

        - tye