Networker

Re: [Networker] Still can't do this in Perl

2004-11-22 12:26:55
Subject: Re: [Networker] Still can't do this in Perl
From: Tim Mooney <mooney AT DOGBERT.CC.NDSU.NODAK DOT EDU>
To: NETWORKER AT LISTMAIL.TEMPLE DOT EDU
Date: Mon, 22 Nov 2004 11:26:01 -0600
In regard to: [Networker] Still can't do this in Perl, George Sinclair said...:

I am still unable to perform the equivalent of the following simple
Bourne shell script in Perl:

#!/bin/sh
/usr/sbin/nsradmin -s orion -i -<<EOF
print type: NSR $1; name: $2
EOF

I invoke this as: ./nsradmin.sh client client_name

This is just an example. My objective is to be able to run the nsradmin
utility from within a Perl script and pass it the desired information
via the Perl script and NOT a temporary file.

As I said in my earlier response on this same thread, if you want to be
able to read and write to the same program and not have the shell
involved, you should look at IPC::Open3.

I submitted this question prior and received some nice suggestions but
none of these worked.

You needed to explore the details of my response to see how to accomplish
it, but it certainly will work.  Proof is after my sig.

Tim
--
Tim Mooney                              mooney AT dogbert.cc.ndsu.NoDak DOT edu
Information Technology Services         (701) 231-1076 (Voice)
Room 242-J6, IACC Building              (701) 231-8541 (Fax)
North Dakota State University, Fargo, ND 58105-5164


#! /usr/bin/perl -w

use strict;
use IPC::Open3;
#
# Since we're only sending a little bit of data, once, we really don't
# need this, I've included it to be robust in the face of future modification.
#
use IO::Select;

my $cmd = '/usr/sbin/nsradmin';
my $srv = 'your_server_name_here';


#
# We require two arguments, the first should be the resource type the query
# should be limited to, the second should be the name of a specific resource
# we want information on.
#
if ($#ARGV != 1) {
       print STDERR "$0: usage: $0 resource_type specific_resource_name\n";
       exit(1);
}

my $rtype = $ARGV[0];
my $rname = $ARGV[1];

my $pid = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $cmd, '-s', $srv, '-i', '-');

$SIG{PIPE} = 'IGNORE';
$SIG{CHLD} = sub {
       print "REAPER: status ", $?/256, " for pid=$pid\n"
               if waitpid($pid, 0) > 0
};

#
# Send our query to nsradmin
#
print CMD_IN "print type: NSR $rtype; name: $rname\n";
#
# We're done sending commands, close the stdin pipe for $cmd.
#
close(CMD_IN);

my $io_s = IO::Select->new();
$io_s->add(*CMD_ERR, *CMD_OUT);

#
# The array of filehandles that are ready for reading
#
my @ready_fhs;

my $fh;

#
# Our accumulated lines from standard output and standard error.
#
my @cmd_err;
my @cmd_out;

while (@ready_fhs = $io_s->can_read()) {
       foreach $fh (@ready_fhs) {
               if (fileno($fh) == fileno(CMD_ERR)) {
                       #print "ERR: ", scalar <CMD_ERR>;
                       push(@cmd_err, scalar(<CMD_ERR>));
               } else {
                       #print "OUT: ", scalar <CMD_OUT>;
                       push(@cmd_out, scalar(<CMD_OUT>));
               }

               $io_s->remove($fh) if eof($fh);
       }
}
close(CMD_OUT);
close(CMD_ERR);

my $line;

print "Standard Error from $cmd:\n";
print "=" x length("Standard Error from $cmd:"), "\n";

#
# spare the user a "use of uninitialize value" warning -- only do this if
# there's more than one line in the array *or* the one line is actually
# defined.  It will be undef() if the child just closed the fd without
# writing anything to it.

if ( ($#cmd_err > 0) or defined($cmd_err[0]) ) {
       foreach $line (@cmd_err) {
               print "$line";
       }
} else {
       print "Nothing written to stderr.\n";
}

print "\n";
print "Standard Output from $cmd:\n";
print "=" x length("Standard Output from $cmd:"), "\n";


if ( ($#cmd_out > 0) or defined($cmd_out[0]) ) {
       foreach $line (@cmd_out) {
               print "$line";
       }
} else {
       print "Nothing written to stdout.\n";
}

--
Note: To sign off this list, send a "signoff networker" command via email
to listserv AT listmail.temple DOT edu or visit the list's Web site at
http://listmail.temple.edu/archives/networker.html where you can
also view and post messages to the list. Questions regarding this list
should be sent to stan AT temple DOT edu
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=