Perl 输出 shell-转义字符串

Perl output shell-escaped string

我正在尝试使用 perl 单行程序将 print0 输出转换为带引号的 shell 参数,有点像 .. | xargs -0 printf "%q" {} 这样的技巧,但我不想要求bash(其 printf 实现 %p)。我有点惊讶,好吧,找不到 在 perl 中执行此操作的简单方法。对于 perl 的所有引用机制,我无法看到 producing 引用字符串。确实是我看的不够仔细。

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

您可以相当简单地为 POSIX-like 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-like shells 绝对不允许将 ' 本身嵌入到单引号字符串中(甚至没有一个转义序列)。


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


可选的背景信息

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

在 Perl 内部,您可以通过使用我的 system() and open(), which allow you to pass the command arguments individually, as-is, but note that this is only an option if your command doesn't use any shell features; for a "shell-less" qx// (`...`) alternative, see this answerlist 形式来完全绕过引用的需要,它也包括 shell-引用 Windows.