Multi-Rsh parallelized rsh program

multi-rsh is a perl script which runs the same command on multiple machines, in parallel, and provides reasonable, adjustable timeouts for those machines which fail to answer. Both standard output and standard error are returned through the same channel, and all output has the hostname prepended to each line.

Multi-rsh must be run as root (remote jobs can be set to run as any user, see Options below). Note that control-C is used to report current status. You can use control-backslash to kill multi-rsh.

Usage

multi-rsh can be used in two forms:
  multi-rsh [options] "command [arg ...]" host [host ...]
and
  multi-rsh [options] -l filename comand [arg ...]
In the first form, the command is a single argument, and must be in quotes according to your shell's own syntax if it includes it's own list of arguments. When the command is executed on the remote system, it will be parsed according to bourne shell (/bin/sh) syntax. (Make sure you properly quote the command to protect any special characters from being interpreted locally).

In the second form, the list of host comes from a file (which may be "-" to represent standard input), and the rest of the arguments are the command to run, and it's arguments. The remote command will also be parsed according to bourne shell (/bin/sh) syntax. (Make sure you properly quote the command to protect any special characters from being interpreted locally).

Neither form allows you to directly pass input to the remote programs. If this is needed, it should be done with Bourne shell redirection.

Options

  • -l filename - described above, takes list of hosts from a file.
  • -p NUMBER - sets the number of parallel connections to keep alive at once, default is 20.
  • -t NUMBER - the number of seconds to allow before giving up. This is the total time to complete both the rsh connection and the command. This value is always seconds. default is 15.
  • -u username - runs the rsh'ed commands as this user.
  • -h - this displays a usage message.

    Examples

    This example sends the same simple command to four different hosts. If a host produces no output, it will not show any lines. If it times out, there will be an error:
      prompt# multi-rsh who host1 host2 host3 host4
      host1: fine       console      Apr 26  3:13
      host1: fine       pts/1        Apr 26  3:14
      host1: fine       pts/3        Apr 26  3:14
      host1: fine       pts/4        Apr 27 11:51
      host3: root       console      Apr  1  4:01
      host4: multi-rsh timeout exceeded, attempting kill HUP 6543
      prompt#
    
    This example demonstrates the same form, but a mulitple-parameter command:
      multi-rsh "cp /etc/sendmail.cf /etc/sendmail.cf.orig" host1 host2 host3 host4
    
    This example demonstrates taking the host list from standard input.
      ypcat hosts | grep foo | awk '{ print $2 }' | multi-rsh -l - grep SCSI /var/adm/messages
    
    This example saves the multi-rsh output to /tmp/output. Compare this command with the next.
      multi-rsh -l /tmp/hostlist date > /tmp/output
    
    This command saves the output for each command into the remote machine's /tmp. Output to standard error will still be displayed locally.
      prompt: multi-rsh -l /tmp/hostlist date \> /tmp/output
    
    This command throws away remote output that goes to standard error (and which would be rerouted to standard output otherwise). multi-rsh may still produce it's own output on standard error, although this is not common.
      prompt: multi-rsh -l /tmp/hostlist date 2\>/dev/null
    
    This command saves the output for each command into a central repository, using different output names for each machine.
      prompt: multi-rsh -l /tmp/hostlist date \> /nfs/public/output.\`hostname\`
    

    Installing

    Change the first line to match the location of your perl. Next, hope it works with your OS. I don't see why it shouldn't, but I've only tested it under Solaris, with perl 5.005_03, 5.6.0, 5.8.0, and 5.8.6.

    Multi-rsh must be run as root. However, it allows you to set the user that the remote program will run as. Do NOT install this script set-uid root, as known security holes exist in the script if it is installed that way.

    Download it now! (version 1.2)

    Change Log

  • Version 1.0 - 4/26/04 - Initial Version
  • Version 1.1 - 5/26/05 - Bug Fix: non-existent host was translated to localhost
  • Version 1.2 - 12/29/06 - Bug Fix: typo at line 90, wrong var in chop

    Design issues

    Separate processes are used because this makes timing out connections much simpler, particularly in perl. Processes are simply killed when they time out. This approach would seem to favor simply calling the system-installed rsh command, however this seems inevitably to lead to problems with local ports left in the TIME_WAIT state. Given that multi-rsh can burn through large numbers of ports quickly, it is entirely possible to get all available reserved ports stuck in TIME_WAIT, making further rsh commands (and some other services) temporarily unnavailable. This implementation has no TIME_WAIT problems on the local machine. See my article "Address already in use" for more information.

    Future enhancements may include: separating standard error; separate timeouts for connection setup and command completion; optional separate output files for each command.


    Tom Fine's Home Send Me Email