#!/bin/sh readonly CONF_LIST="$1" readonly SERVER_LIST="$2" help() { printf "Usage: $(basename $0) cmd_list server_list\n" >&2 printf " cmd_list: A text file containing a list of commands to run.\n" >&2 printf " server_list: A text file containing a list of servers to\n" >&2 printf " connect to and run commands on.\n\n" >&2 printf "All commands will be allocated to the first available server.\n" >&2 printf "Each command must be valid on every server.\n" >&2 printf "The output will be saved to a text file on the remote systems.\n" >&2 exit 1 } run_server() { server="$1" loop="/tmp/$(basename $PIPE_NAME .fifo)-$server.fifo" mkfifo "$loop" while read cmd; do out_file="$(echo "$cmd" | sed 's/[[:space:].\/]/_/g;s/-//g').out" printf "$cmd > $out_file\necho\n" printf "$server: $cmd\n" >&2 read line < "$loop" > /dev/null # Block until command completes done | ssh -oBatchMode=yes -oStrictHostKeyChecking=no "$server" "sh" > "$loop" rm "$loop" echo "Server '$server' finished!" >&2 } main() { PIPE_NAME="$(mktemp /tmp/distributer-XXX.fifo)" rm "$PIPE_NAME" mkfifo "$PIPE_NAME" sed '/^[[:space:]]*$/d' "$CONF_LIST" > "$PIPE_NAME" & cat "$SERVER_LIST" | while read server; do run_server "$server" < "$PIPE_NAME" > /dev/null & echo $! done | while read pid; do wait $pid done rm "$PIPE_NAME" echo "All jobs finished!" } if [ "$#" -eq 2 ]; then main else help fi