#!/bin/sh # # $Id: rshall 807 2011-08-19 08:22:04Z rp $ # rshall: rsh with multiple hosts, *last* arg is command # with -i, also accepts input ... I'd rather dup stdin or so, but how? # tmpfile tmpfile=/tmp/rshall-$$ rm='/bin/rm' # error handling trap "$rm"' -f $tmpfile; exit' 1 2 3 4 13 15 PATH=/usr/tuelocal/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/usr/etc; export PATH #host=host #finger=finger grep=grep cat=cat sed=sed rsh=ssh #--- cmdline parsing ---# # Puke() { if [ -n "$*" ]; then echo Fatal error: $* 1>&2; fi $cat <&2 Usage: $0 [-v] [-i] [-e] [-b] [-u user] [-H] [-Y] [-P] host1 [host2 [...]] "command" to issue "rsh host command" for every host use -i flag to supply input, -e to redirect stderr to stdout, -v for progress messages, -b to start in the background, -u user to connect as the given user, -H to check the hostnames with 'host', -Y to check them with 'ypmatch', -P to check them with 'ping' note: the effect of -i is to call rsh without the -n flag take care: -b may fill up your process table if used on many hosts ZZ exit 1 } input= hostlist= verbose= bg= check_w_host= check_w_ypmatch= check_w_ping= user_prefix= while : do case "$1" in -h|-help|\?*) Puke;; -b) bg=1 if [ -n "$command" ]; then Puke "options must precede arguments"; fi;; -i) input=1 if [ -n "$command" ]; then Puke "options must precede arguments"; fi;; -v) verbose=1 if [ -n "$command" ]; then Puke "options must precede arguments"; fi;; -e) errtoout=1 if [ -n "$command" ]; then Puke "options must precede arguments"; fi;; -u) shift; user_prefix="$1@" if [ -n "$command" ]; then Puke "options must precede arguments"; fi;; -H) check_w_host=1 if [ -n "$command" ]; then Puke "options must precede arguments"; fi;; -Y) check_w_ypmatch=1 if [ -n "$command" ]; then Puke "options must precede arguments"; fi;; -P) check_w_ping=1 if [ -n "$command" ]; then Puke "options must precede arguments"; fi;; -*) Puke "$1 is not a valid option" ;; "") break;; *) hostlist="$hostlist $command"; command=$1;; esac shift done if [ -z "$command" ] then Puke "no command supplied" fi if [ -z "$hostlist" ] then Puke "no host(s) supplied" fi case "$user_prefix" in -*) Puke "no -u argument supplied" ;; esac if [ -n "$check_w_host" ] then for h in $hostlist do if host 2>&1 >/dev/null then Puke "ypmatch cannot find '$h'" fi done fi if [ -n "$check_w_ypmatch" ] then for h in $hostlist do if ypmatch hosts 2>&1 >/dev/null then Puke "ypmatch cannot find '$h'" fi done fi #-- OK, start doing useful things ---# # if [ -n "$input" ] then # read input! $cat >$tmpfile # we can do away with the $tmpfile, with a fork for every host ... fi Rsh() { case "$errtoout" in "") $rsh "$@" | $sed "s/^/$h: /" ;; *) $rsh "$@" 2>&1 | $sed "s/^/$h: /" ;; esac } Rsh_w_tmp() { if [ -f "$tmpfile" ] then $cat $tmpfile | Rsh "$@" else Rsh -n "$@" fi } for h in $hostlist do if [ -z "$check_w_ping" ] || ping $h 2 >/dev/null # note: "2 >" # host is active then #if [ -z "`$finger @$h 2>&1 | $grep 'Connection refused$'`" ] # host accepts finger - very crude check to see if rsh will work # however, finger has been disabled since, where I live if true then if [ -n "$verbose" ] then echo "executing '$command' on '$h'" 1>&2 fi case "$bg" in "") Rsh_w_tmp $user_prefix$h "$command" ;; *) Rsh_w_tmp $user_prefix$h "$command" & ;; esac fi fi done $rm -f $tmpfile