使用Perl的QX {} /`...`运营商的参数列表

时间:2019-02-01 22:17:16

标签: perl backticks qx

systemexecopen '|-'open2等。所有这些都允许我将命令指定为要作为参数列表运行,并将其直接传递给{ {1}}而不是通过外壳运行。

即使execvp足够聪明,如果它看起来像一个“简单”命令,也可以直接运行它,这免除了我用正确的shell换码并带有所有令人讨厌的陷阱的麻烦。

示例:

perl

代替

open my $out, '|-', $prog, @args;
system $prog, @args;
exec $prog, @args;

open my $out, "|$prog @args"; system "$prog @args"; exec "$prog @args"; 运算符是否具有等效项?还是您必须始终手动完成此操作?

qx//

3 个答案:

答案 0 :(得分:5)

模块IPC::System::Simple作为函数User.findAll({ ... order: [ [ Address, 'distance', 'DESC' ] ] }); 提供了qx运算符的列表形式(此外,与该模块中的其他函数一样,如果存在执行错误或非零响应代码,你可以调整)。另外,您可以使用Capture::Tiny来包装核心capturex调用并提供相同的行为,但是它还具有可以将STDERR一起包装或与STDOUT分开包装的其他功能。

system

在芯管开放是在大多数情况下是唯一的选择,除了IPC::Open3这是类似的复杂但允许引导STDERR以及

答案 1 :(得分:5)

以下是一些简单的选项。

  • String::ShellQuote + qx

    use String::ShellQuote qw( shell_quote );
    my $cmd = shell_quote(@cmd);
    my $output = `$cmd`;
    
  • IPC::System::Simple

    use IPC::System::Simple qw( capturex );
    my $output = capturex(@cmd)
    
  • IPC::Run3

    use IPC::Run3 qw( run3 );
    run3(\@cmd, \undef, \my $output);
    
  • IPC::Run

    use IPC::Run qw( run );
    run(\@cmd, \undef, \my $output);
    

第一个解决方案涉及外壳,但没有其他解决方案。

答案 2 :(得分:0)

事实证明(不幸的是),这并不是我所忽略的-唯一的解决方案实际上是使用open -|或使用其他答案中列出的外部模块之一。

反引号implementation(无论是由qx/.../`...`还是readpipe调用)在硬连线上可以接受单个字符串参数:

PP(pp_backtick)
{
    dSP; dTARGET;
    PerlIO *fp;
    const char * const tmps = POPpconstx;
    const U8 gimme = GIMME_V;
    const char *mode = "r";

    TAINT_PROPER("``");
    if (PL_op->op_private & OPpOPEN_IN_RAW)
        mode = "rb";
    else if (PL_op->op_private & OPpOPEN_IN_CRLF)
        mode = "rt";
    fp = PerlProc_popen(tmps, mode);
    ...

请注意,POPpconstx会从堆栈中弹出一个参数,并使用PerlProc_popen而不是PerlProc_popen_list