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!

2
  • If you got enough permissions to install a script, you have enough permissions to install a module.
    – ikegami
    May 7, 2014 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 7, 2014 at 20:03

1 Answer 1

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")
1
  • 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 8, 2014 at 9:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.