al@io.ee.pitt.edu (Alan Martello) (05/04/90)
I have a perl script which must rsh to another system and run specific commands (depending on the result of querying the system with other commands). The following works as expected: open (RSH_FH, "rsh othermachine ls |"); but is a little too clunky for my needs (I don't want an open for each command). Instead, I'd prefer something like the following: open (RSH_FH, "| rsh othermachine |"); That is, I want to read AND write to the same rsh process. For example, the first thing I need to do is to supply a password if logging in as a different user. I tried minimal experimentation and couldn't get it to do the desired thing... Perhaps a perl/shell wizard can shed some light on the feasability of my endeavor. I though about trying to use forks, etc. but didn't try it. Ideas? ******************************************************************* Alan R. Martello Electrical Engineering Dept. al@ee.pitt.edu University of Pittsburgh *******************************************************************
henkp@ruuinf.cs.ruu.nl (Henk P. Penning) (05/04/90)
In article <7497@pitt.UUCP> al@io.ee.pitt.edu (Alan Martello) writes: >Instead, I'd prefer something like the following: > open (RSH_FH, "| rsh othermachine |"); >That is, I want to read AND write to the same rsh process. Here is my solution. Subroutine open2(READHANDLE,WRITEHANDLE,arg,arg,...) expects names of a READHANDLE and a WRITEHANDLE (as strings). It sets up pipes, forks, and calls exec(arg,arg,...) in the child. The example should print the first few lines of the sorted passwd file. === HenkP === Henk P. Penning, Dept of Computer Science, Utrecht University. Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands. Telephone: +31-30-534106 e-mail : henkp@cs.ruu.nl (uucp to hp4nl!ruuinf!henkp) --------------------------------------------------- sub open2 # ( READHANDLE, WRITEHANDLE, argument(s) to exec() ) { local($p1,$p2,@execParms) = @_ ; eval "pipe($p1,APPOUT)" || die "open2 can't create pipe $p1/APPOUT" ; eval "pipe(APPIN,$p2)" || die "open2 can't create pipe APPIN/$p2" ; $open2Pid = fork ; if ( $open2Pid == 0 ) # CHILD { close($p1) || die "child can't close $p1" ; close($p2) || die "child can't close $p2" ; close(STDIN) || die "child can't close STDIN" ; close(STDOUT) || die "child can't close STDOUT" ; open(STDIN, "<&APPIN") || die "child can't redirect STDIN" ; open(STDOUT,">&APPOUT") || die "child can't redirect STDOUT" ; close(APPIN) || die "child can't close APPIN" ; close(APPOUT) || die "child can't close APPOUT" ; exec(@execParms) ; die "open2 can't exec " . join(' ',@execParms) ; } else # PARENT { close(APPIN) || die "open2 can\'t close APPIN" ; close(APPOUT) || die "open2 can\'t close APPOUT" ; } } sub flush # ( FILEHANDLE ) { $oldselect = select($_[0]) ; $oldpipe = $| ; $| = 1 ; print "" ; $| = $oldpipe ; select($oldselect) ; } $INP = 'INP' ; $OUT = 'OUT' ; &open2($INP,$OUT,'sort | head') ; open(PW,'/etc/passwd') || die "can't open /etc/passwd\n" ; while ($_ = <PW> ) { print OUT "out> $_" ; } close(OUT) || die "can't close OUT\n" ; while ( $_ = <INP> ) { print "<in $_" ; } close(INP) || die "can't close INP\n" ; --------------------------------------------------- -- Henk P. Penning, Dept of Computer Science, Utrecht University. Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands. Telephone: +31-30-534106 e-mail : henkp@cs.ruu.nl (uucp to hp4nl!ruuinf!henkp)