将带引号的字符串传递给 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() 保持引号不变的主要内容,如果未能解决你的问题,请参考以下文章

将带引号的变量传递给React中的函数

通过 TeamCity 将带引号的参数传递给 PowerShell 脚本

Java Regex 用于将带引号的字符串与转义引号匹配

如何将带单引号的字符串转换为双引号以进行 json 解析

使用正则表达式将带引号的字符串与嵌入的非转义引号匹配

如何将带引号的多字字符串替换为参数?