not logged in | [Login]

scripts/for each host

#!/bin/bash
# Source: Ari Polsky

function num_jobs() {
    NUM_JOBS=$(jobs | grep Running | wc -l)
    if [ "$NUM_JOBS" == "" ]; then
        NUM_JOBS=0
    fi
}

function usage() {
cat << EOF
usage: for-each-host -f <host_file> [OPTIONS] <COMMAND>

OPTIONS:
-a              asynchronous mode
-m CONCURRENCY  maximum number of concurrent asynchronous operations (async mode only)
-d DIR          output directory (async mode only, defaults to _for_each_host_output)
EOF
}

BATCH_SIZE=20
DELAY=5
POLLING_INTERVAL=1

while getopts "hs:b:af:d:m:" opt; do
  case $opt in
    h)
        usage
        exit 0
        ;;
    f)
        FILE=$OPTARG
        ;;
    d)
        OUTDIR=$OPTARG
        ;;
    a)
        ASYNC=1
        ;;
    s)
        DELAY=$OPTARG
        ;;
    b)
        BATCH_SIZE=$OPTARG
        ;;
    m)
        MAX_CONCURRENCY=$OPTARG
        ;;
    \?)
        echo "Invalid option: -$OPTARG" >&2
        usage
        exit 1
        ;;
    :)
        echo "Option -$OPTARG requires an argument." >&2
        exit 1
        ;;
  esac
done

shift $((OPTIND-1))
COMMAND=$@

if [ "$FILE" == "" ]; then
    echo missing required -f \<filename\> option
    usage
    exit 1
fi

if [ "$ASYNC" == "1" ] && [ "$OUTDIR" == "" ]; then
    OUTDIR=_for_each_host_output
fi

if [ "$OUTDIR" != "" ]; then
    mkdir -p $OUTDIR
fi

SSH_OPTIONS="-o PasswordAuthentication=no -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ForwardAgent=yes"

COUNT=0
while read HOST; do
    if [ "$ASYNC" == "1" ]; then
        echo executing for host $HOST
        ssh $SSH_OPTIONS $HOST 2>/dev/null -o ConnectTimeout=10 "$COMMAND" </dev/null > $OUTDIR/$HOST &
        if [ "$MAX_CONCURRENCY" != "" ]; then
            num_jobs
            while [ "$NUM_JOBS" -ge "$MAX_CONCURRENCY" ]; do
                sleep $POLLING_INTERVAL
                num_jobs
            done
        else
            COUNT=$((COUNT+1))
            if [ $COUNT == $BATCH_SIZE ]; then
                COUNT=0
                sleep $DELAY
            fi
        fi
    else
        OUTPUT=$(ssh $SSH_OPTIONS $HOST -o ConnectTimeout=10 "$COMMAND" </dev/null)
        if [ "$OUTDIR" == "" ]; then
            echo "$HOST ";
            echo "--------------------------------";
            echo "$OUTPUT"; echo "";
        else
            echo "$OUTPUT" > $OUTDIR/$HOST
        fi
    fi
done<$FILE

if [ "$ASYNC" == "1" ]; then
    while [ "$NUM_JOBS" -ge 1 ]; do
	    printf "."
        sleep $POLLING_INTERVAL
        num_jobs
    done
fi