【问题标题】:Escaping parentheses in perl backticks for bash command为 bash 命令转义 perl 反引号中的括号
【发布时间】:2020-06-19 15:25:32
【问题描述】:

多年来我一直在使用反引号,但这是我第一次尝试使用带括号的命令。我遇到了一个我无法弄清楚的错误。

我尝试在多个位置添加双引号并使用 \ 转义,但似乎没有任何效果。任何帮助将不胜感激。

命令 $file5$file6 是 perl 变量,而不是 bash。

@array = `/usr/bin/join -j 1 -t, <(cat $file5 | awk -F, '{print \$3","\$1}' | sort) <( cat $file6 | awk -F, '{print \$3","\$1}' | sort) `

错误: AH01215: sh: -c: line 0: 意外标记 `(', referer:

附近的语法错误

【问题讨论】:

  • 我认为错误消息中的sh 是这里的重要提示。 POSIX 未指定进程替换(&lt;(...) 语法),并且您的系统的 sh 似乎不支持它。您可能需要显式调用 Bash,或者自己协调进程通信。
  • 您是否有不想直接在 Perl 程序中执行此操作的原因?

标签: bash perl


【解决方案1】:

反引号使用/bin/sh,虽然&lt;( ... ) 可以被bash 识别,但它不能被bourne shell 识别。如果使用反引号,则需要使用

my $bash_cmd = ...;
my @lines = `bash -c $bash_cmd`;

可以使用String::ShellQuote 来构建shbash shell 命令。

use String::ShellQuote qw( shell_quote );

my $file5_quoted = shell_quote($file5);
my $file6_quoted = shell_quote($file6);

my $awk_cmd = shell_quote("awk", "-F,", '{print $3","$1}');

my $bash_cmd = '/usr/bin/join -j 1 -t,'
   . " <( $awk_cmd $file5_quoted | sort )"
   . " <( $awk_cmd $file6_quoted | sort )";

my $sh_cmd = shell_quote("bash", "-c", $bash_cmd);
my @lines = `$sh_cmd`;

我们可以使用IPC::System::Simplecapturex 来避免启动过多的shell,并提供错误检查。为此,请将上面的最后两行替换为以下内容:

use IPC::System::Simple qw( capturex );

my @lines = capturex("bash", "-c", $bash_cmd);

【讨论】:

    【解决方案2】:

    一种解决方法是创建一个从 perl 接受两个文件名的 shell 脚本,使用这两个输入文件处理连接,并将结果返回到 perl 数组。

    #1。创建包含以下四行的 join.sh: 猫 $1 | awk -F, '{打印 $3","$1}' |排序 > 1.out 猫 $2 | awk -F, '{打印 $3","$1}' |排序 > 2.out /usr/bin/join -j 1 -t, 1.out 2.out rm 1.out 2.out #2。修改您的 perl 语句以调用 join.sh,如下所示: @array=`join.sh $file5 $file6`;

    【讨论】:

    • 缺乏解释。缺少舍邦。遭受四个代码注入错误。文件名选择不当。 (Fixed code)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 2014-01-21
    • 2015-05-29
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    相关资源
    最近更新 更多