This problem applies to Perl v5.24.0 on Windows 10
Except for the simplest cases. It is always a problem passing command lines and parameter lists between programs. Taking into account the effects of whitespace and shell metacharacters, possibly so that the data remains intact over several levels of calls, can involve a mess of escapes and quotation marks
The panacea has always been to use the multiple-parameter form of system
(which also tries to avoid calling the shell as an intermediary) so that each parameter is reliably separated without resorting to quotes
A call like this
system("dir \"C:\\Program Files\\\"")
is much easier on the eye written like this
system('dir', 'C:\Program Files\\')
However, I can see no way to pass values that include enclosing quotes
If I write a test program
use Data::Dump;
dd \@ARGV;
and then call
system('show', 'xxx')
then the output I get is what I expect
["xxx"]
However, suppose I want to pass the string "xxx"
. If I try
system('show', '"xxx"')
then the quotes are stripped at some point along the way and the output is identical to the preceding example
system
such that the output is ["\"xxx\""]
?I have tried all manner of escaping, but the solution evades me
The problem:
system($^X, '-E', 'say @ARGV', '"test"');
Output:
test
That's so broken![1]
Solution:
use Win32::ShellQuote qw( quote_system );
system(quote_system($^X, '-E', 'say @ARGV', '"test"'));
Output:
"test"
Perl needs to build a command line even if the shell isn't used. Unlike unix where the system call to execute a program takes the path to a program and a list of arguments, the Windows system call to execute a program takes a command line, so a command line must be built even if the shell is avoided. It appears that Perl builds the command lines incorrectly.[2] This is why using the system BLOCK LIST
syntax doesn't help.
In fact, it's up to the application to parse the command line for arguments! Thankfully, there's a system call to do that, so a standard has formed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With