【问题标题】:Is it possible to get system(@args) to preserve shell metacharacters?是否可以让 system(@args) 保留 shell 元字符?
【发布时间】:2013-07-14 08:22:29
【问题描述】:

考虑以下涉及管道的命令:

$ echo Hi | tee test.log
Hi

基于perldoc exec:

如果LIST 中有多个参数,或者LIST 是一个数组 如果有多个值,则使用 LIST 中的参数调用 execvp(3)如果只有一个标量参数或包含一个元素的数组 它,检查参数是否有 shell 元字符,如果有 任何,整个参数被传递给系统的命令外壳 解析(在 Unix 平台上是 /bin/sh -c,但在其他平台上有所不同 平台)。如果参数中没有 shell 元字符,它 被拆分成单词直接传给execvp,这样更 高效。


基于此,以下命令不会 tee 输出:

$ perl -Mstrict -wle 'my @args = ( "Hi", "| tee test.log" );
                      system( "echo", @args );'
Hi | tee test.log

而这个是:

$ perl -Mstrict -wle 'my @args = ( "Hi", "| tee test.log" );
                      system( join " " => "echo", @args );'
Hi

问题不在于如何tee,而在于如何在系统命令中进行管道传输(否则File::Tee 就足够了)。

我觉得能够以@args 形式提供多个管道而不必求助于命令字符串化可能很有用。

【问题讨论】:

  • 不,你不能用 system() 那样做。当您使用多个参数调用它时,不涉及 shell。
  • @Barmar : 如果 system 无法使用,是否有通过 CPAN 模块的替代接口?

标签: perl system


【解决方案1】:

如果您需要将system()的列表形式与重定向、管道等混合使用,则使用CPAN模块IPC::Run

use IPC::Run 'run';
run ["echo", "Hi"], "|", ["tee", "rso.log"] or die;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    • 2010-12-12
    • 1970-01-01
    相关资源
    最近更新 更多