Perl输出shell转义字符串

时间:2017-01-11 07:30:08

标签: perl shell escaping quoting

我试图使用perl单行将print0输出转换为引用的shell参数,有点像.. | xargs -0 printf "%q" {}之类的技巧,但我不想要要求bash(其printf实现%p)。我很惊讶,找不到在perl中执行此操作的简单方法。对于所有perl的引用机制,我没有看到生成引用的字符串。当然,我看起来还不够好。

希望答案不是正则表达式。引用一个精心设计的正则表达式放入shell命令行并不是我的乐趣(如果只有一个简单的perl程序可以为我引用它,哦回到同样的问题)。

1 个答案:

答案 0 :(得分:2)

您可以非常简单地为类似POSIX的shell推送自己的引用 - 不需要复杂的正则表达式(只需使用文字直接替换字符串):

$ echo "I'm \$HOME. 3\" of rain." | perl -lne "s/'/'\\\''/g; print q{'} . \$_ . q{'}"
'I'\''m $HOME. 3" of rain.'

该方法是在AppleScript的quoted form of命令之后建模的:

输入字符串被'分解为子字符串,每个子字符串本身为' - 用原始的'字符括起来。在子串之间拼接为\'(单独引用')。

当传递给shell时,shell会将这些部分重建为单个文字字符串。

这种多部分字符串连接方法是必要的,因为类似POSIX的shell绝对不允许在单引号字符串中嵌入'本身(甚至没有转义序列)。

或者,您可以安装CPAN模块,例如ShellQuote

可选背景信息

虽然Perl本身支持这样的引用机制来拼凑存储在单个字符串中的shell命令以传递给qx//`...`)会很方便,但这样的机制必须运行平台特异性
值得注意的是,Windows的引用规则与Unix平台的规则非常不同,除了简单的情况外,shell命令整体上也是不兼容的。

从Perl内部,您可以通过使用system()open()列表形式完全绕过引用的需要,这样您就可以通过按原样单独命令参数,但请注意,如果您的命令不使用任何 shell 功能,这只是一个选项;对于“无壳”qx//`...`)替代方案,请参阅我的this answer,其中还包括 Windows 上的shell引用。