Skip to content

Instantly share code, notes, and snippets.

@inthecloud247
Forked from sroaj/gist:3027112
Created July 2, 2012 05:10
Show Gist options
  • Save inthecloud247/3031213 to your computer and use it in GitHub Desktop.
Save inthecloud247/3031213 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 -i key.pem server2 server3 < get_date.sh
# command.sh -tbv -l cap -i ~/keys/cap.pem ${app_[@]} < build.sh
IDENTITY_FILE_OPTION=
REMOTE_CMD=
DEFAULT_USER_OPTION=
BATCH_OPTION=
ERROR_TERMINATE=
VERBOSE=
_read_from_flag=
_cumulative_result=
if [ -t 0 ]; then
_read_from_flag=1
else
REMOTE_CMD=$(cat <&0)
fi
usage () {
cat << EOF
Usage: `basename $0` [-btv] [-i identity_file] [-l default_user]
[-c bash_commands] [user@]host1 ... [user@]host2 [< command_file]
EOF
}
while getopts “:hbtvi:c:l:” 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 [ $_read_from_flag ]; then
REMOTE_CMD="$OPTARG"
else
echo "Error: Cannot combine stdin and input script"
usage
exit 1
fi
;;
l)
DEFAULT_USER_OPTION="-l "`cut -d ' ' -f1 <<< "$OPTARG"`
;;
?)
usage
exit
;;
esac
done
shift $(( OPTIND - 1 ))
if [ "$_read_from_flag" -a ! "$REMOTE_CMD" ] ; then
echo "Error: No command specified, either \"-s 'bash_commands'\" or \"< 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 [ "$_read_from_flag" ]; 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