【问题标题】:Perl properly escaping string with various different quotesPerl 使用各种不同的引号正确转义字符串
【发布时间】:2014-06-05 04:28:21
【问题描述】:

我正在用 Perl 编写一个脚本,我有一个 Hash of Hash,看起来像这样

my %hash = (
    "ITEM"   => {
      "cmd" => "find / \( -wholename '/home/homedir/*' -prune -o -wholename '/proc/*' -prune \) -o \( -type f -perm -0002 \) -exec ls -l '{}' ';' 2>/dev/null",
    },

);

现在我使用的命令使用各种不同的引号。例如

find / \( -wholename '/home/homedir/*' -prune -o -wholename '/proc/*' -prune \) -o \( -type f -perm -0002 \) -exec ls -l '{}' ';' 2>/dev/null

当我运行 perl 脚本时,像这样的复杂命令不会运行并抛出诸如

之类的错误
perl -e '$cmd=`find / \( -wholename '/home/homedir/*' -prune \) -o \( -type d -perm -0002 \) -exec ls -ld '{}' ';' 2>/dev/null | grep root` ; print $cmd'

在 -e 第 1 行的 EOF 之前的任何位置都找不到字符串终止符“`”。

或者一些基于语法错误的命令。我猜这与 Perl 处理带引号的字符串的方式有关。

如何正确引用这些字符串,尽可能使用最少的转义字符。换句话说。我应该如何引用这个字符串,以便我可以像上面那样编写哈希,并且不会由于引号不同而出现语法错误?

【问题讨论】:

  • 您可以使用File::Find 来避免调用带有所有这些讨厌的嵌套引号的shell。

标签: perl


【解决方案1】:

您不能单独使用单引号。您需要使用'\'' 正确转义它们:

perl -e '$cmd=`find / \( -wholename \'/home/homedir/*\' -prune \) -o \( -type d -perm -0002 \) -exec ls -ld \'{}\' \';\' 2>/dev/null | grep root` ; print $cmd'

一些替代版本:

使用双引号而不是单引号作为perl -e 的限制符:

perl -e "$cmd=`find / \( -wholename '/home/homedir/*' -prune \) -o \( -type d -perm -0002 \) -exec ls -ld '{}' ';' 2>/dev/null | grep root` ; print $cmd"

当你想使用最后一个版本时,你需要用q{}qq{} 引用字符串来修改你的哈希:

my %hash = (
    "ITEM"   => {
      "cmd" => q{find / \( -wholename '/home/homedir/*' -prune -o -wholename '/proc/*' -prune \) -o \( -type f -perm -0002 \) -exec ls -l '{}' ';' 2>/dev/null},
    },
);

q{} 是单引号,qq{} 是双引号。

编辑:你也可以看看String::ShellQuote

【讨论】:

    【解决方案2】:

    您需要在 shell 级别转义单引号。

    为了演示,下面相当于命令行中的print "'\n";

    perl -e 'print "'\''\n"'
    

    输出:

    '
    

    因此,您需要在命令中将任何 ' 转换为 '\''

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-29
      • 1970-01-01
      • 1970-01-01
      • 2016-05-06
      • 1970-01-01
      • 2017-08-18
      相关资源
      最近更新 更多