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

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
  • Comment on Re: Filename Surrounded by Quotes in a Scalar Variable Causes Open to Fail
  • Download Code

Replies are listed 'Best First'.
Re^2: Filename Surrounded by Quotes in a Scalar Variable Causes Open to Fail
by roho (Bishop) on Sep 03, 2020 at 21:21 UTC
    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)

        Understood. You're right. If Perl started removing quote characters without permission that would open the door to all sorts of unintended consequences.

        I'm focused on developing on Windows at the moment, and I forgot about the other environments (*nix, etc.) that have different rules and allow different characters in filenames.

        Thanks again for your input and clarification.

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

      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.

        Thanks ikegami. You're right. Windows requires quotes around filenames that contain a space in cmd commands (and interestingly, Windows automatically puts quotes around paths in shortcuts when the path name contains a space).

        "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.

      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";
        Thanks perlfan. pryrt cleared up my misunderstanding in the initial posts with him above.

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