将带引号的字符串传递给system(),保持引号不变

时间:2016-07-06 10:34:44

标签: perl exec quotes

此问题适用于Windows 10上的Perl v5.24.0

除最简单的情况外。在程序之间传递命令行和参数列表总是一个问题。考虑到空白和shell元字符的影响,可能使数据在几个级别的调用中保持不变,可能涉及到一堆转义和引号

灵丹妙药一直使用system的多参数形式(它也试图避免将shell作为中介调用),这样每个参数都可以可靠地分离而不需要求引号

像这样的电话

system("dir \"C:\\Program Files\\\"")

在这样的眼睛上写得更容易

system('dir', 'C:\Program Files\\')

但是,我看不到传递包含封闭引号的值

如果我写一个测试程序

show.pl

use Data::Dump;
dd \@ARGV;

然后致电

system('show', 'xxx')

然后我得到的输出是我期望的

["xxx"]

但是,假设我想传递字符串"xxx"。如果我试试

system('show', '"xxx"')

然后在路上的某个点剥离引号,输出与前面的示例相同

如何调用system以使输出为["\"xxx\""]

我已经尝试过各种逃避行为,但解决方案避开了我

1 个答案:

答案 0 :(得分:4)

问题:

system($^X, '-E', 'say @ARGV', '"test"');

输出:

test

那太破了! [1]

解决方案:

use Win32::ShellQuote qw( quote_system );

system(quote_system($^X, '-E', 'say @ARGV', '"test"'));

输出:

"test"
  1. 即使没有使用shell,Perl也需要构建一个命令行。与执行程序的system call获取程序路径和参数列表的unix不同,执行程序的Windows system call采用命令行,因此即使是命令行也必须构建避免使用shell。看来Perl错误地构建命令行。 [2] 这就是为什么使用system BLOCK LIST语法没有帮助。

  2. 实际上,它由应用程序来解析参数的命令行!值得庆幸的是,system call要做到这一点,所以已经形成了一个标准。