将带引号的字符串传递给 system() 保持引号不变
Posted
技术标签:
【中文标题】将带引号的字符串传递给 system() 保持引号不变【英文标题】:Passing a quoted string to system() keeping quotes intact 【发布时间】:2016-11-08 09:10:15 【问题描述】:此问题适用于 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\""]
?
我已经尝试了各种逃避方式,但解决方案却逃避了我
【问题讨论】:
您在 Windows 上使用哪种 perl?我刚刚在 Cygwin 上使用 perl 5.22.2 对其进行了测试,它正是您所要求的。也许像 activestate perl 这样的东西表现不同? 我的是草莓 Perl v5.24.0。请您将您的确切电话发布到system
?
使用 perl 5.14.4 在 Cygwin 上也适用于我
谢谢@xxfelixxx。谁能确认我自己的结果?
【参考方案1】:
问题:
system($^X, '-E', 'say @ARGV', '"test"');
输出:
test
太坏了![1]
解决方案:
use Win32::ShellQuote qw( quote_system );
system(quote_system($^X, '-E', 'say @ARGV', '"test"'));
输出:
"test"
即使不使用 shell,Perl 也需要构建命令行。与 unix 中执行程序的 system call 采用程序路径和参数列表不同,Windows 执行程序的 system call 采用命令行,因此即使避免使用 shell,也必须构建命令行. Perl 似乎错误地构建了命令行。[2]这就是为什么使用 system BLOCK LIST
语法没有帮助的原因。
事实上,由应用程序来解析命令行参数!值得庆幸的是,有一个 system call 可以做到这一点,因此已经形成了一个标准。
【讨论】:
以上是关于将带引号的字符串传递给 system() 保持引号不变的主要内容,如果未能解决你的问题,请参考以下文章