Perl输出shell转义字符串



我正试图使用perl one-liner将print0输出转换为带引号的shell参数,这有点像.. | xargs -0 printf "%q" {},但我不想需要bash(其printf实现%p)。我有点惊讶,没有发现在perl中实现这一点的简单方法。对于perl的所有引用机制,我没有看到生成引用字符串的方法。当然,我只是看得不够认真。

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

您可以非常简单地为类似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()list形式来完全绕过引用的需要,这允许您按原样单独传递命令参数,但请注意,这只是一个选项,如果您的命令不使用任何shell功能;关于"无外壳"qx//(`...`)的替代方案,请参阅我的答案,其中也包括Windows上的外壳引用。

最新更新