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

Passing a quoted string to system() keeping quotes intact

提问人:Borodin 提问时间:7/6/2016 最后编辑:CommunityBorodin 更新时间:7/18/2016 访问量:633

问:

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

除了最简单的情况。在程序之间传递命令行和参数列表始终是一个问题。考虑到空格和 shell 元字符的影响,可能使数据在多个调用级别上保持完整,可能会涉及一堆转义和引号

灵丹妙药一直是使用 的多参数形式(这也试图避免将 shell 称为中介),以便可靠地分离每个参数,而无需诉诸引号system

像这样的电话

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\""]

我尝试了各种逃避方式,但解决方案避开了我

Perl exec 行情

评论

0赞 ChatterOne 7/6/2016
您在 Windows 上使用哪种 perl?我刚刚用 perl 5.22.2 在 Cygwin 上测试了它,它完全符合您的要求。也许像 activestate perl 这样的东西行为不同?
0赞 Borodin 7/6/2016
我的是 Strawberry Perl v5.24.0。请问您能将您的确切电话发布到吗?system
0赞 xxfelixxx 7/6/2016
在带有 perl 5.14.4 的 Cygwin 上也适用于我
0赞 Borodin 7/6/2016
谢谢@xxfelixxx。任何人都可以确认我自己的结果吗?

答:

4赞 ikegami 7/6/2016 #1

问题:

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

输出:

test

太坏了![1]


溶液:

use Win32::ShellQuote qw( quote_system );

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

输出:

"test"

  1. Perl 需要构建一个命令行,即使没有使用 shell。与 unix 不同,在 unix 中,执行程序的系统调用采用程序的路径和参数列表,而执行程序的 Windows 系统调用采用命令行,因此即使避免使用 shell,也必须构建命令行。Perl 似乎错误地构建了命令行。[2] 这就是为什么使用语法无济于事的原因。system BLOCK LIST

  2. 事实上,由应用程序来解析参数的命令行!值得庆幸的是,有一个系统调用来做到这一点,所以一个标准已经形成。