Skip to content

Instantly share code, notes, and snippets.

@sroaj
Created July 1, 2012 06:27
Show Gist options
  • Save sroaj/3027112 to your computer and use it in GitHub Desktop.
Save sroaj/3027112 to your computer and use it in GitHub Desktop.
#!/bin/bash
# [Purpose]
# execute a command on remote servers
# note: we are basically rolling our own pssh here, without the parallelism
#Example: command.sh -tv -c "date" server1 special@server2 server3
# command.sh -tv -c "date" -i key.pem -l "user" server1 special@server2 server3
# command.sh -tv -s get_date.sh -i key.pem server2 server3
# command.sh -tbv -s build.sh -l cap -i ~/keys/cap.pem ${app_[@]}
IDENTITY_FILE_OPTION=
REMOTE_CMD=
DEFAULT_USER_OPTION=
BATCH_OPTION=
ERROR_TERMINATE=
VERBOSE=
_input_command_as_string=
_cumulative_result=
usage () {
cat << EOF
Usage: `basename $0` [-btv] [-i identity_file] [-l default_user]
-c bash_commands|-s command_file [user@]host1 ... [user@]host2
EOF
}
while getopts “:hbtvi:c:l:s:” OPTION; do
case $OPTION in
h)
usage
exit 1
;;
b)
BATCH_OPTION="-o BatchMode=yes"
;;
t)
ERROR_TERMINATE=1
;;
v)
VERBOSE=1
;;
i)
if [ -e "$OPTARG" ]; then
IDENTITY_FILE_OPTION="-i $OPTARG"
else
echo "Warning: Identity file $OPTARG not accessible: No such file or directory."
fi
;;
c)
if [ $REMOTE_CMD ]; then
echo "Error: Cannot combine input command and file"
usage
exit 1
else
REMOTE_CMD="$OPTARG"
_input_command_as_string=1
fi
;;
s)
if [ $REMOTE_CMD ]; then
echo "Error: Cannot combine input command and file"
usage
exit 1
elif [ -e "$OPTARG" ]; then
REMOTE_CMD="$OPTARG"
else
echo "Error: Input file not found"
usage
exit 1
fi
;;
l)
DEFAULT_USER_OPTION="-l "`cut -d ' ' -f1 <<< "$OPTARG"`
;;
?)
usage
exit
;;
esac
done
shift $(( OPTIND - 1 ))
if [ ! "$REMOTE_CMD" ] ; then
echo "Error: No command specified, either \"-c 'bash_commands'\" or \"-s command_file\" required"
usage
exit 1
fi
if ! (( ${#@} )); then
echo "Error: No host specified"
usage
exit 1
fi
if [ $VERBOSE ]; then
exec 3>&1
else
exec 3>/dev/null
fi
for SERVER in "$@"; do
(( i++ ))
_time=$( date +'%H:%m:%S' )
if [ $VERBOSE ]; then echo -e "\x1B[36m[$i:${#@}]\x1B[0m $_time \x1B[33m[WORKING]\x1B[0m $SERVER"; fi
# the bottom one should not have command line length limitations
if [ "$_input_command_as_string" ]; then
errors=$( { ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $BATCH_OPTION $IDENTITY_FILE_OPTION $DEFAULT_USER_OPTION $SERVER "$REMOTE_CMD" ; } 2>&1 1>&3 )
_result=$?
else
errors=$( { ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $BATCH_OPTION $IDENTITY_FILE_OPTION $DEFAULT_USER_OPTION $SERVER 'bash -s' < "$REMOTE_CMD" ; } 2>&1 1>&3 )
_result=$?
fi
_time=$( date +'%H:%m:%S' )
(( _cumulative_result |= $_result ))
echo -n -e "\x1B[36m[$i:${#@}]\x1B[0m $_time "
if (( $_result )); then
echo -e "\x1B[1;31m[FAILURE]\x1B[0m $SERVER \x1B[1;31mExited with error code $_result\x1B[0m"
if [ "$errors" ]; then
echo -e "\x1B[31mStderr:\x1B[0m $errors"
fi
if [ $ERROR_TERMINATE ];then
echo -e "\x1B[31m[TERMINATING]\x1B[0m As requested"
break;
fi
else
echo -e "\x1B[32m[SUCCESS]\x1B[0m $SERVER"
fi
done
exec 3>&-;
exit $_cumulative_result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment