Article 8914 of comp.lang.perl: Xref: feenix.metronet.com comp.lang.perl:8914 Newsgroups: comp.lang.perl Path: feenix.metronet.com!news.utdallas.edu!hermes.chpc.utexas.edu!cs.utexas.edu!howland.reston.ans.net!europa.eng.gtefsd.com!emory!news-feed-2.peachnet.edu!concert!theo!mcnc!sps From: sps@mcnc.org (Stephen P. Schaefer) Subject: Re: Remote perl scripts In-Reply-To: friedric@rsoc.rockwell.com's message of 10 Dec 1993 18: 43:22 GMT Message-ID: Sender: daemon@mcnc.org (David Daemon) Nntp-Posting-Host: robin.mcnc.org Organization: Microelectronics Center of North Carolina References: <2eag0a$l91@popeye.jsc.nasa.gov> Date: Wed, 15 Dec 1993 03:55:21 GMT Lines: 241 I found code to do this for shell scripts in this group, signed by Bruce Barnett who in turn credits Randal (could it be anyone other than Mr. Schwartz?). There should be a way to invoke perl from the rsh. I modified the code for our situation: normally my rsh's are authenticated transparently by kerberos, but if that fails, we've modified rsh to prompt for a password for authentication. If I'm going to multiple machines, I can't tell who I'm typing at, so I wanted that to just fail -- thus the importance of detaching the subprocesses from the tty. I try to report failures. I tweaked the man page and a couple other things, so assume that all bugs were introduced by me. With a root ticket, this is great for some administrative tasks like muxrsh chmod u-s /usr/bin/X11/xterm < my_unix_hosts I've also reworked this as a couple packages for use in perl scripts that do multiple host updates; I'll post once I'm happier with the documentation. Stephen P. Schaefer, Sys. Admin. MCNC sps@mcnc.org P.O. Box 12889 (919) 248-1417 RTP, NC 27709 DISCLAIMER: The opinions expressed above are those of the author and are unrelated to the positions or policies of MCNC. WARNING: In response to a suit by members of the print media, MCNC has signed a consent decree which places in the public record any correspondence to or from its employees which does not relate to scientific or technological research, and which has not been designated as confidential by an industrial participant. Please bear this in mind when you correspond with me. public(x) :- not(research(x)),not(industryparticipant(y),private(x,y)). #! /usr/local/std/bin/perl 'di'; 'ig00'; # -*-Perl-*- # This is a mux version of rsh # it will do several rsh commands in parallel # just the thing for doing "df -t 4.2" on 400 machines # # Bruce Barnett # (Thanks to Randal for hard part) # # default number of processes is 8, # but is resettable using the -m argument # # usage: # muxrsh [-m max] [-v] [-l username] command [args ...] ) { chop $machine; $verbose && printf "forking for %s with %d alive\n", $machine, &alive; &wait() if &alive >= $maxpids; $pid = fork; die "fork: $!" unless defined $pid; if ($pid) { # parent $pids{$pid} = $machine; } else { # this is to cause failure when prompting for a password close(STDIN); if (open(TTY,"/dev/tty")) { # excerpted from /usr/include/sys/ioctl.h: # /* #define IOC_VOID 0x20000000 /* no parameters */ # /* #define _IO(x,y) (IOC_VOID|('x'<<8)|y) */ # /* #define TIOCNOTTY _IO(t, 113) /* void tty association */ $TIOCNOTTY = 536900721; ioctl(TTY, $TIOCNOTTY, 0); close(TTY); } $results=`exec rsh $machine $remoteuser -n \'@ARGV\' 2>&1 `; # this makes sure "machine: " is before each line returned. @mresults = (split(/\n/, $results)); for $mresult (@mresults) { print "$machine: $mresult\n"; } exit 0; } } &wait() while &alive > 0; } #-------------- # main routine # $|++; # flush buffers on a line-by-line basis $verbose = 0; # assume verbose is off $maxpids = 8; # default maximum number of processes $remoteuser=""; %pids = (); # zero out the pids &getswitches(); # get any switches/changes to defaults @ARGV || die "Must specify a command to be executed!\n"; $verbose && $remoteuser && print "remote user is $remoteuser\n"; $verbose && print "Max number of processes is $maxpids\n"; &doit(); # tuit 0; ############################################################### # These next few lines are legal in both Perl and nroff. .00; # finish .ig 'di \" finish diversion--previous line must be blank .nr nl 0-1 \" fake up transition to first page again .nr % 0 \" start at page 1 '; __END__ ##### From here on it's a standard manual page ##### .\" MCNC $Header: muxrsh.pl,v 1.1 92/06/30 12:11:36 bin Exp $ .\" Copyright 1988 by the Microelectronics Center of North Carolina .TH MUXRSH 1 "June 29, 1992" .AT 3 .SH NAME muxrsh \- run a command on a number of different machines .SH SYNOPSIS .B muxrsh [-m max] [-v] [-l username] command [args ...] line \fInumber\fP. You've run out of processes. The default limit is 8 simultaneous invocations, requiring 1+2*8 processes \(em a coordinating perl process; one perl process per host; and an rsh process per host. Use .B \-m to reduce the parallelism. .TP hostname: rsh: Remote protocol failure. Some unspecified error. .TP hostname: rsh: Cannot disable echo. The rsh attempted to prompt you for a password: you need pasword-less entry to the remote host; I recommend Kerberos. .TP hostname: rsh: Connection timed out. The host's rsh service didn't respond in a timely manner. .SH BUGS The quoting necessary to get shell metacharacters to the remote machines is revolting. An example: .sp muxrsh echo foo \e\e \e| tr o O \e\e \e; hostname .sp The above is equvalent to .sp echo foo | tr o O; hostname .sp on each host. The ``double backslash space backslash'' idiom is an implementation artifact. .PP I don't know how to fix ``Remote protocol failure.'' .SH SEE ALSO kinit(1), rsh(1) -- Stephen P. Schaefer, Sys. Admin. MCNC sps@mcnc.org P.O. Box 12889 (919) 248-1417 RTP, NC 27709 NCSC has been reorganized as the Information Technologies division of MCNC; no decision has been made on revision of the domain name. DISCLAIMER: The opinions expressed above are those of the author and are unrelated to the positions or policies of MCNC. WARNING: In response to a suit by members of the print media, MCNC has signed a consent decree which places in the public record any correspondence to or from its employees which does not relate to scientific or technological research, and which has not been designated as confidential by an industrial participant. Please bear this in mind when you correspond with me. public(x) :- not(research(x)),not(industryparticipant(y),private(x,y)).