Skip to content

Instantly share code, notes, and snippets.

@melnik13 melnik13/servers
Last active Aug 29, 2015

Embed
What would you like to do?
To run a command on a bunch of servers, so you can say: spread.sh --command 'rm -rf / &' --grep-criteria '#centos|#msdos'
#
# The format is following:
# hostname:username:port:ssh-key #comments #tags
# All parameters besides of the first are optional
#
# Regular servers
host1
host2
host3
# The servers where we shall use an alternative username to log in
host4:user
# Servers where we shall use an alternative port to log in
host5::30022
host6:user:30022
# Servers where we shall use an alternative SSH-key to log in
host7:::~/.ssh/id_rsa.zaloopa
host8:user::~/.ssh/id_rsa.zaloopa
host9:user:30666:~/.ssh/id_rsa.zaloopa
# Servers we need to be found by some hashtags (so we can run the script with the -g parameter: "-g '#huerga'")
host10 #huerga
host11:user #huerga
host12:user:30022 #huerga #zaebis #pizdets
host13:user:30022:~/.ssh/id_rsa.zaloppa #huerga #pizdets
#!/bin/bash
OPTS=$(getopt -n $(basename ${0}) -o c:g:y -l command:,grep-criterias:yes -- "${@}")
if [ "${?}" -ne 0 ]; then
echo "Can't get options" >&2
exit 1
fi
eval set -- "${OPTS}"
while :; do
case "${1}" in
-c|--command)
COMMAND="${2}"; shift 2;;
-g|--grep-criterias)
CRITERIAS="${2}"; shift 2;;
-y|--yes)
SURE="Y"; shift 1;;
--)
shift; break;;
*)
echo "Can't recognize the option: ${1}"; exit 1;;
esac
done
TARGETS=$(cat ~/etc/servers | grep -E "${CRITERIAS}" | sed -e 's/[[:space:]]*#.*$//' -e '/^$/d')
if [ -z "${COMMAND}" ]; then
echo "The command is undefined" >&2
exit 1
fi
while :; do
echo -e "Our targets are:\n${TARGETS}" >&2
[ "${SURE}" != "Y" ] && read -p "Are you sure you want to run '${COMMAND}'? (Y/N) " SURE
case "${SURE}" in
[Yy])
for TARGET in ${TARGETS}; do
HOST=$(echo "${TARGET}" | sed -r -n -e 's/^([^:]+)(:([^:]*))?(:([^:]*))?(:([^:]*))?$/\1/gp')
USER=$(echo "${TARGET}" | sed -r -n -e 's/^([^:]+)(:([^:]*))?(:([^:]*))?(:([^:]*))?$/\3/gp')
PORT=$(echo "${TARGET}" | sed -r -n -e 's/^([^:]+)(:([^:]*))?(:([^:]*))?(:([^:]*))?$/\5/gp')
SKEY=$(echo "${TARGET}" | sed -r -n -e 's/^([^:]+)(:([^:]*))?(:([^:]*))?(:([^:]*))?$/\7/gp')
[ -z "${USER}" ] && USER=$(whoami)
[ -z "${PORT}" ] && PORT=22
[ -z "${SKEY}" ] && SKEY=~/.ssh/id_rsa
echo "Running '${COMMAND}' on ${HOST}:${PORT}..." >&2
ssh -i "${SKEY}" -p "${PORT}" -l "${USER}" "${HOST}" "${COMMAND}"
done
break
;;
[Nn])
break
;;
*)
echo "So, Y or N?" >&2
;;
esac
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.