2

I have made a custom sub to run various terminal-command in perl using Open3.

I encounter a strange problem with snmpwalk, when i run the command in terminal it work, but with Open3 it won't.

The sub is this:

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 );
}

I call it with:

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

If i want to run the following command:

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

It return as $err:

snmpwalk: No securityName specified

If i run the exact same command in terminal, it return my results:

NETAPP-MIB::aggrName.1 = STRING: "SAS2"

NETAPP-MIB::aggrName.2 = STRING: "SATA1"

...

I've found that NET::SNMP may solve my probleme, but i can't install it due to hardened linux OS with no install option possible.

I don't realy understand why it doesn't work.

perl -v: 5.8.8

Thanks!

Community
  • 1
  • 1
  • If you got enough permissions to install a script, you have enough permissions to install a module. – ikegami May 07 '14 at 19:59
  • 1
    `$out = <$outfh>; $err = <$errfh>;` will cause a deadlock if the child outputs enough to STDERR. I recommend using IPC::Run3 or IPC::Run instead of the still very low-level IPC::Open3. If you want to stick with IPC::Open3, you'll have to use IO::Select, threads or some form of asynchronous IO to avoid the possibility of deadlock. – ikegami May 07 '14 at 20:03

1 Answers1

1

The problem is the "-c public v1" argument:

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

The IPC::Open3 open3() function does a fork then exec. exec bypasses the shell when given a list of arguments. So the list needs to be broken down into individual arguments:

($res, $err) = run_cmd("snmpwalk", "-c", "public", "-v1", "somehostname", "NETAPP-MIB::aggrName")
dwarring
  • 4,794
  • 1
  • 26
  • 38
  • Exactly. To elaborate, the message "No securityName specified" is printed because snmpwalk thinks you want SNMP v3, which is the default version if no -v flag is given. So, obviously the -v1 flag was not received, just as snoopy pointed out. – Jolta May 08 '14 at 09:19