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!
$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.