Linux IPC::Open3以与独立snmwalk命令不同的行为运行snmpwalk

Linux IPC::Open3以与独立snmwalk命令不同的行为运行snmpwalk,linux,perl,snmp,linux-from-scratch,popen3,Linux,Perl,Snmp,Linux From Scratch,Popen3,我使用Open3制作了一个自定义sub,用于在perl中运行各种终端命令 我在snmpwalk中遇到了一个奇怪的问题,当我在终端中运行该命令时,它可以工作,但在Open3中它不能 分包商是: sub run_cmd { my ( $cmd, @args ) = @_; my ( $infh, $outfh, $errfh, $pid, $out, $err ); use Symbol 'gensym'; $errfh = gensym(); # open3

我使用Open3制作了一个自定义sub,用于在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 );
}
如果要运行以下命令:

snmpwalk-c public-v1主机名NETAPP-MIB::aggrName

它以$err的形式返回:

snmpwalk:未指定securityName

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

NETAPP-MIB::aggrName.1=字符串:“SAS2”

NETAPP-MIB::aggrName.2=字符串:“SATA1”

我发现NET::SNMP可以解决我的问题,但我无法安装它,因为经过强化的linux操作系统没有可能的安装选项

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

perl-v:5.8.8

谢谢

问题在于
“-c public v1”
参数:

($res, $err) = run_cmd("snmpwalk", "-c public -v1", "somehostname", "NETAPP-MIB::aggrName");
然后,
IPC::Open3 Open3()
函数执行以下操作<当给定参数列表时,code>exec绕过shell。因此,需要将列表分解为各个参数:

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

如果您有足够的权限安装脚本,则您有足够的权限安装模块。
$out=$错误=将导致死锁。我建议使用IPC::Run3或IPC::Run,而不是仍然非常低级的IPC::Open3。如果您想坚持使用IPC::Open3,您必须使用IO::Select、线程或某种形式的异步IO来避免死锁的可能性。更详细地说,打印消息“No securityName specified”是因为snmpwalk认为您需要SNMP v3,如果没有给出-v标志,这是默认版本。因此,正如史努比指出的那样,显然没有收到-v1标志。
($res, $err) = run_cmd("snmpwalk", "-c", "public", "-v1", "somehostname", "NETAPP-MIB::aggrName")