Skip to content

Instantly share code, notes, and snippets.

@tsuchm
Created May 2, 2018 23:25
Show Gist options
  • Save tsuchm/05b949dea00e8141f42720635145b05a to your computer and use it in GitHub Desktop.
Save tsuchm/05b949dea00e8141f42720635145b05a to your computer and use it in GitHub Desktop.
Run sudo on remote machines
#!/bin/bash
usage(){
cat <<EOF
Usage: remote-sudo host0 host1 ... hostN -- command arg0 arg1 ... argN
EOF
}
ALLHOSTS=(node0 node1 node2 node3 node4 node5 node6 node7 node8 node9)
DOMAIN=example.jp
PATH=/usr/bin:/bin
declare -a hosts
declare -a commands
declare -a files
login=${USER}
while [ "$#" -gt 0 ]; do
case ${1} in
-n|--debug)
if [ -z "${commands[*]}" ]; then
debug='true'
else
commands=(${commands[@]} ${1})
fi
;;
-h|--help)
if [ -z "${commands[*]}" ]; then
usage
exit 0
else
commands=(${commands[@]} ${1})
fi
;;
-l|--login)
if [ -z "${commands[*]}" ]; then
login=${2}
shift
else
commands=(${commands[@]} ${1})
fi
;;
-a|--all)
if [ -z "${commands[*]}" ]; then
hosts=(${hosts[@]} ${ALLHOSTS[@]})
else
commands=(${commands[@]} ${1})
fi
;;
--)
hosts=(${hosts[@]} ${commands[@]})
commands=(${2})
shift
;;
-*)
if [ -z "${commands[*]}" ]; then
echo "Unknown option: ${1}" 1>&2
exit 3
else
commands=(${commands[@]} ${1})
fi
;;
*)
if [ -z "${commands[*]}" ]; then
if ( type ${1} 1>/dev/null 2>&1 ); then
commands=(${1})
if [ -z "${hosts[*]}" ]; then
hosts=(${ALLHOSTS[@]})
fi
else
hosts=(${hosts[@]} ${1})
fi
else
if [ -f ${1} ]; then
case ${1} in
/etc/*|/usr/*|/var/*)
commands=(${commands[@]} ${1})
;;
/home/*|*)
files=(${files[@]} ${1})
commands=(${commands[@]} /tmp/`basename ${1}`)
;;
esac
else
commands=(${commands[@]} ${1})
fi
fi
;;
esac
shift
done
if [ -z "${commands[*]}" ]; then
usage
exit 0
fi
SSH=(ssh)
SCP=(scp)
if [ -z "${debug}" ]; then
read -p "Password for ${login}@${hosts[*]}: " -s passwd
echo
dir=`mktemp -d -t remote-sudo.XXXXXXXXXX`
else
SSH=(echo 'DRYRUN: ' ${SSH[@]})
SCP=(echo 'DRYRUN: ' ${SCP[@]})
dir=/tmp/remote-sudo.XXXXXXXXXX
fi
for h in ${hosts[@]}
do
case ${h} in
*.*) ;;
*) h=${h}.${DOMAIN};;
esac
echo "============ ${h} ============"
if ( ! ${SSH[@]} -x -f -T -o 'ControlMaster yes' -o 'ControlPath '"${dir}/${h}" ${login}'@'${h} sleep 60 ); then
echo "Cannot login to ${login}@${h}" 1>&2
exit 1
fi
if [ ! -z "${files[*]}" ]; then
echo scp -p ${files[@]} ${login}'@'${h}:/tmp/
${SCP[@]} -p -o 'ControlMaster no' -o 'ControlPath '"${dir}/${h}" ${files[@]} ${login}'@'@${h}:/tmp/
fi
if [ -z "${debug}" -a ! -S "${dir}/${h}" ]; then
if ( ! ${SSH[@]} -x -f -T -o 'ControlMaster yes' -o 'ControlPath '"${dir}/${h}" ${login}'@'${h} sleep 60 ); then
echo "Cannot login to ${login}@${h}" 1>&2
exit 1
fi
fi
if ( echo ${passwd}|${SSH[@]} -T -o 'ForwardX11 no' -o 'ControlMaster no' -o 'ControlPath '"${dir}/${h}" ${login}'@'${h} "sudo -K && sudo -S -p '' true" 1>/dev/null 2>&1 ); then
echo ssh ${login}'@'${h} sudo ${commands[@]}
${SSH[@]} -x -t -o 'ControlMaster no' -o 'ControlPath '"${dir}/${h}" ${login}'@'${h} env LANG=C sudo ${commands[@]}
else
echo "Failed executing sudo at ${login}@${h}" 1>&2
exit 2
fi
done
if [ -z "${debug}" ]; then
rm -rf ${dir}
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment