############################################################################################## # This subroutine receives command string as a first parameter and sends it to the remote host. # Then it collects the output of the command as one big string ($CommandOutput). # End of the command is determined # by the prompt REGEX that is passed as the second argument to the function. # showprogress argument is to control echoing of the output of the command to the terminal # 0 - do not show, 1- verbose, 2 - show '#' sign for every new received chunk of command output # CommandOutput argument is to return output of the command to calling code for post-processing # 04/14/06 Sergey A. Belous # ******************************************************************************************* # 05/02/06 passing file handles correctly into subroutine # 04/18/08 made as separate library for use in inline PERL PLUGINs # 04/28/13 changed to "non-blocking select/sysread" (gco3.pl) to be able to reuse PLUGINs # in the GNU screen as robot filters ("Ctrl-a" ":" "exec !!. perl plugin.pl") # ******************************************************************************************* # example how to call: # gco(\*STDIN,\*STDOUT,\*STDERR,"show sub aaa user $ARGV[0]\r\n","#",0, $buffer); ############################################################################################## use IO::Select; sub gco{ my $myin = shift; my $myout = shift; my $myerr = shift; my $commandtoexecute = shift; my $promptregex = shift; my $showprogress = shift; #end of argument list, last one is in $_[0] #write command to shell and then do non-blocking non-buffered read till prompt is found syswrite $myout,"$commandtoexecute"; $CommandOutput=""; my $read_set = new IO::Select();#Create handle set for reading $read_set->add($myin);#add the reader handle to the set while() { if ($read_set->can_read(0)) { sysread $myin,$greeting,10000; if($showprogress==1){syswrite $myerr,$greeting} if($showprogress==2){syswrite $myerr,"#"} $CommandOutput.=$greeting; if($CommandOutput =~/$promptregex/){last} } } $read_set->remove($myin);#remove the reader handle from the set $CommandOutput =~ s/[\r\x00]//g;#clean-up $_[0]=$CommandOutput; } 1;