#!/bin/sh # # multissh.sh, Copyright © 2013, 2019 Matteo Cypriani # (Formerly named cluster-run.sh) # # This program is free software. It comes without any warranty, to # the extent permitted by applicable law. You can redistribute it # and/or modify it under the terms of the Do What The Fuck You Want # To Public License, Version 2, as published by Sam Hocevar. See # http://sam.zoy.org/wtfpl/COPYING for more details. # # Run a command on a list of remote hosts using Parallel SSH. #set -x set -u # Exit codes readonly EXIT_SUCCESS=0 readonly EXIT_USAGE=127 readonly EXIT_DEPENDENCY=4 readonly EXIT_HOSTS_LIST=6 print_usage() { echo "Usage: $0 [-l login] " } bad_usage() { err "$@" echo >&2 print_usage >&2 exit $EXIT_USAGE } err() { printf 'Error! ' >&2 printf '%s\n' "$@" >&2 } # Do we have at least a host list and a command? [ $# -lt 2 ] && bad_usage "Wrong number of arguments." # Parse the optional arguments LOGIN= if [ "$1" = "-l" ] ; then LOGIN="$2" shift shift # Do we still have at least a host list and a command? [ $# -lt 2 ] && bad_usage "Wrong number of arguments." fi # Check dependencies PSSH=$(command -v parallel-ssh || command -v pssh) if [ -z "$PSSH" ] ; then err "Parallel SSH (pssh) is required for this script to work." exit $EXIT_DEPENDENCY fi # Hosts list file [ -z ${XDG_CONFIG_HOME+x} ] && XDG_CONFIG_HOME="$HOME/.config" HOSTS_LIST_NAME="$1" shift HOSTS="$XDG_CONFIG_HOME/ssh_tools/${HOSTS_LIST_NAME}.lst" echo "Using file '$HOSTS' as hosts list." if [ ! -f "$HOSTS" ] ; then err "The hosts list file doesn't exist or is not a regular file." exit $EXIT_HOSTS_LIST fi # Login if [ -n "$LOGIN" ] ; then echo "Login: $LOGIN" LOGIN="-l $LOGIN" fi echo "Command:" "$@" # shellcheck disable=SC2086 exec $PSSH --print $LOGIN -h "$HOSTS" -- "$@"