#!/bin/sh - # eachhost - run the given command for each host listed on stdin # Steve Kinzler, kinzler@cs.indiana.edu, Oct 93 # http://www.cs.indiana.edu/~kinzler/home.html#unix case "$RSHCMD" in *ssh) s=s;; *) s=;; esac p=; v=; V=; o=; output=; d=; delay=; l=; user=; bad= i=; input=/dev/null (test -t 0 < /dev/tty) 2> /dev/null && input=/dev/tty while : do case $# in 0) break;; *) case "$1" in -S) s=;; -s) s=s;; -p) p=p;; -v) v=v;; -w) v=w;; -V) V=' ';; -W) V=' ';; -n) i=n; input=/dev/null;; -i) i=i; shift; input="$1";; -o) o=o; shift; output="$1";; -d) d=d; shift; delay="$1";; -l) l=l; shift; user="-l $1";; --) shift; break;; -h) bad=t; break;; -*) bad=t; echo "$0: unknown option ($1)" 1>&2;; *) break;; esac shift;; esac done case "$bad" in ?*) cat << EOF 1>&2 usage: $0 [ -S | -s ] [ -p ] [ -v | -w ] [ -V | -W ] [ -n ] [ -i file ] [ -o prefix ] [ -d seconds ] [ -l user ] [ command ] The given command is run remotely on each host listed on stdin. -S use rsh/remsh/rcmd, default \$RSHCMD or rsh -s use ssh, default \$RSHCMD or rsh -p prompt before processing each host -v print each hostname before processing it -w like -v but with the hostname highlighted -V label any output lines with the hostname -W like -V but with a tab following the label -n close stdin on each command run -i provide each command with the given file on stdin -o place the output of each command in a local file named by the given prefix plus the hostname -d abort commands after the given number of delay seconds -l run remote commands using the given user login No command implies a remote login to the host. If the command contains the string "\$host", it is run locally rather than remotely with the current hostname substituted for "\$host". The default stdin for the commands is /dev/tty if available and /dev/null if not. EOF exit 1;; esac safe= case "$d" in ?*) if (safe -d 3 /bin/csh -fc :) 2> /dev/null then safe=safe test "$delay" -ne 0 && safe="$safe -d $delay" else echo "$0: ignoring delay ($delay), safe(1) unavailable" 1>&2 fi;; esac case "$s" in ?*) rsh=ssh;; *) if test -f /usr/bin/remsh; then rsh=/usr/bin/remsh elif test -f /usr/bin/rcmd; then rsh=/usr/bin/rcmd else rsh=rsh fi;; esac trap continue 2 while read host do case "$p" in ?*) echo "$host? [n] " | tr -d '\012' read ans < /dev/tty case "$ans" in [yY]*) ;; *) continue;; esac;; esac case "$v" in w) echo "========== $host ==========";; ?*) echo "$host";; esac case "$*" in *\$host*|*\${host*) case "$o$V" in o?) eval "$@" < "$input" 2>&1 | sed "s/^/$host:$V/" > "$output$host";; o) eval "$@" < "$input" > "$output$host" 2>&1;; ?) eval "$@" < "$input" 2>&1 | sed "s/^/$host:$V/";; *) eval "$@" < "$input";; esac;; *) case "$o$V" in o?) $safe $rsh "$host" $user ${1+"$@"} < "$input" 2>&1 | sed "s/^/$host:$V/" > "$output$host";; o) $safe $rsh "$host" $user ${1+"$@"} < "$input" \ > "$output$host" 2>&1;; ?) $safe $rsh "$host" $user ${1+"$@"} < "$input" 2>&1 | sed "s/^/$host:$V/";; *) $safe $rsh "$host" $user ${1+"$@"} < "$input";; esac;; esac done