Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Filename Surrounded by Quotes in a Scalar Variable Causes Open to Fail

by roho (Bishop)
on Sep 03, 2020 at 20:58 UTC ( [id://11121332]=perlquestion: print w/replies, xml ) Need Help??

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

I am running the script below in Strawberry Perl 5.24.1 on Windows 10. When quotes are added to a filename in a scalar variable, open fails with error message "Invalid argument". The docs for open did not shed any light on this issue.

It doesn't seem right that the presence of quotes surrounding a filename in a scalar variable should cause open to fail. When the line in the script that adds the surrounding quotes is commented out, open works fine.

Your thoughts?

#!/usr/bin/perl use strict; use warnings; my $temp_file = $ENV{'APPDATA'} . '\test.tmp'; $temp_file = '"' . $temp_file . '"'; print "|$temp_file|\n"; open(my $fh, '>', $temp_file) or die "Error opening $temp_file $!\n";

"It's not how hard you work, it's how much you get done."

  • Comment on Filename Surrounded by Quotes in a Scalar Variable Causes Open to Fail
  • Download Code

Replies are listed 'Best First'.
Re: Filename Surrounded by Quotes in a Scalar Variable Causes Open to Fail
by pryrt (Abbot) on Sep 03, 2020 at 21:04 UTC
    That's because there's no such filename with quotes in the filename itself. The quotes are used on the Windows command line and similar environments to make sure that Windows knows the spaces are meant as part of the filename, but in a lower-level access like the perl open command, you don't need quotes in the string.

    #!/usr/bin/perl use strict; use warnings; my $temp_file = $ENV{'APPDATA'} . '\test file name.tmp'; #$temp_file = '"' . $temp_file . '"'; # not needed, because open() isn +'t bothered by spaces in the name print "|$temp_file|\n"; open(my $fh, '>', $temp_file) or die "Error opening $temp_file $!\n"; print "worked!\n";


    edit: canonical reference = https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
    except for the following ... reserved characters: ...
    * " (double quote)
    ...
    ... thus indicating that quotes are not part of the filename, because they are not allowed
      Thanks for your response pryrt. I know that Windows requires quotes if a file or directory name contains spaces, but it just seems odd that Perl's open doesn't just ignore the surrounding quotes. In my case, I use the quoted filename in the scalar variable other places for other things, so now I will make sure they are not present for open.

      "It's not how hard you work, it's how much you get done."

        it just seems odd that Perl's open doesn't just ignore the surrounding quotes

        It would seem odd (and a bug) to me if Perl's open did just ignore the quote characters in the string I pass as the filename. If I send a string to that third argument of open, that is the exact text I want as the filename. If Perl started ignoring my characters without my permission, I'd get annoyed.

        And in Linux environments, quotes are perfectly valid characters inside filenames, so if I wanted my file named `"QuotedFilename"` in Linux, and Perl silently stripped those characters for me, I'd really be annoyed.

        I use the quoted filename in the scalar variable other places for other things

        In that case, I would store the filename variable as the actual name of the file, and then properly quote it for whatever environment you're sending that filename to. The quoting is part of the environment's requirement, not part of the filename. (By "environment", I don't mean %ENV; I mean it in the sense of "All the elements that affect a system or its inputs and outputs." -- wiktionary:environment)

        The underlying system calls for open accept a C string on both POSIX and Windows. The double-quote character is perfectly valid in filenames on POSIX, but forbidden on Windows — this is why you are getting an "Invalid argument" error. Wrapping the file name in quotes is valid on both POSIX (under a Bourne shell) and Windows when forming shell commands, but Perl's open does not involve the shell and simply passes the string you give it to the system.

        I know that Windows requires quotes if a file or directory name contains spaces

        This is incorrect. Windows system calls include CreateFile, the call used to create file handles and possibly files, takes a path, not a quoted path.

        You may need to use quote paths in shell commands to ensure the path is correctly passed to the program. But just like Windows, open expects a path, not a fragment of a shell command.

        >it just seems odd that Perl's open doesn't just ignore the surrounding quotes.

        I think you're missing the point. You made the double quotes part of the literal filename when you defined it. The double quotes around names with spaces also works on unix shells because the shell knows to treat the contents of the double quotes as a single string. perl nor open cares about meta characters (like quotes) in strings. It takes the whole string literally. You should have simply not had the $temp_file = '"' . $temp_file . '"'; line:

        #!/usr/bin/perl use strict; use warnings; $temp_file = '"' . $temp_file . '"'; #<- delebe this! my $temp_file = $ENV{'APPDATA'} . '\test.tmp'; print "|$temp_file|\n"; open(my $fh, '>', $temp_file) or die "Error opening $temp_file $!\n";
Re: Filename Surrounded by Quotes in a Scalar Variable Causes Open to Fail
by ikegami (Patriarch) on Sep 04, 2020 at 07:59 UTC

    It's quite simple: Double-quotes are not allowed in file names in Windows.

    The error you get from File Explorer when you try to create a file name that contains double-quotes: image.

Re: Filename Surrounded by Quotes in a Scalar Variable Causes Open to Fail
by BillKSmith (Monsignor) on Sep 03, 2020 at 22:47 UTC
    I do not remember the situation, but I know that in the distant past, I was once forced to use the "8.3" alias of a file name in a call to the system function. I did not like it, but it did solve the quoting problem.
    Bill
      Yes, there is such a thing as an 8.3 filename. Wikki 8.3 filename. I haven't thought about this for more than a decade, but such a thing exists. Although with modern Windows file systems, this is not necessary. There were some limitations for example with the file system used on the 1.2 MB floppies. This has gone the way of the Dodo bird.

        Nothing to do with floppy disks per se. 8.3 filenames were a limitation of the 16-bit version of FAT; FAT32 introduced longer filenames but each file had an 8.3 alias which was used for compatibility with applications that hadn't been updated for FAT32. Not just on floppies, but hard disks too. Pretty sure it applied similar logic to non-FAT filesystems too, like NTFS, CD-ROMs, SMB shares, etc. The feature is likely still in existence, but applications that still use FAT16 API calls will be vanishingly rare.

        The windows shell requires double quotes around paths which contain spaces. This is true even if the shell is called from perl. The OP's syntax is correct in this case. Ten years ago, I could not figure that out so I devised a "workaround" (shown as a comment below). The "8dot3" names do not contain spaces so they do not need the extra quotes. Although I do not recommend it, it still works on my Windows 7.
        use strict; use warnings; my $browser = 'C:\Program Files\Internet Explorer\iexplore.exe'; $browser = '"' . $browser . '"'; #my $browser = 'C:\PROGRA~1\INTERN~1\iexplore.exe'; #workaround exec $browser;
        Bill

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11121332]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-18 04:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found