IPC :: Open3运行snmpwalk,其行为与独立snmwalk命令不同

时间:2014-05-07 18:53:35

标签: linux perl snmp lfs popen3

我已经使用Open3在perl中运行了各种终端命令。

我在snmpwalk遇到一个奇怪的问题,当我在终端中运行命令时它工作,但是使用Open3它不会。

子是:

sub run_cmd {
    my ( $cmd, @args ) = @_;
    my ( $infh, $outfh, $errfh, $pid, $out, $err );

    use Symbol 'gensym';
    $errfh = gensym();    # open3 does not init stderr, we have to do it.

    output( "run_cmd: $cmd @args\n", 2, 1 ); #for debug
    eval { $pid = open3( $infh, $outfh, $errfh, $cmd, @args ); } or do {
        if ($@) {
            output("Error: open3 error $@\n");
            exit $CODES{CRITICAL}; #exit 2;
        }
    };
    {   # anonym block to limit $/ redefinition
        local $/ = undef;
        $out = <$outfh>;
        $err = <$errfh>;
    }
    return ( $out, $err );
}

我称之为:

 ($res, $err) = run_cmd("snmpwalk", "-c public -v1", "somehostname", "NETAPP-MIB::aggrName");

如果我想运行以下命令:

  

snmpwalk -c public -v1 somehostname NETAPP-MIB :: aggrName

以$ err:

返回
  

snmpwalk:未指定securityName

如果我在终端中运行完全相同的命令,它会返回我的结果:

  

NETAPP-MIB :: aggrName.1 = STRING:“SAS2”

     

NETAPP-MIB :: aggrName.2 = STRING:“SATA1”

     

...

我发现NET :: SNMP可以解决我的问题,但由于硬件化的Linux操作系统没有安装选项,我无法安装它。

我真的不明白为什么它不起作用。

perl -v:5.8.8

谢谢!

1 个答案:

答案 0 :(得分:1)

问题是"-c public v1"参数:

($res, $err) = run_cmd("snmpwalk", "-c public -v1", "somehostname", "NETAPP-MIB::aggrName");

IPC::Open3 open3()函数执行fork然后exec。给定参数列表时,exec会绕过shell。因此,列表需要分解为单个参数:

($res, $err) = run_cmd("snmpwalk", "-c", "public", "-v1", "somehostname", "NETAPP-MIB::aggrName")