upgradebest.sh is a small BASH script which executes the same command via ssh on many Unix servers. If the command requires root privileges, upgradebest.sh asks you once for your sudo password and uses it on all servers. A pseudo-tty is allocated so that commands requiring user input can be run as well.

One example use (and the main purpose why I wrote this tool) is to run "aptitude -y upgrade" on all your Debian servers after cron-apt has informed you by mail about pending updates and you have reviewed those updates. Thus, "aptitude -y upgrade" is the default command of the tool. The script basically does the same as writing ssh -to "ConnectTimeout 10" server command for every one of your servers but saves you from having to reenter your sudo password every time.

The script can be downloaded here: upgradebest.sh.

Source Code (and Usage Notes and Examples)

#!/bin/bash -e

# Usage: upgradebest.sh [-e ssh_options] [-c command] [server ...]
# Executes "sudo aptitude -y upgrade" or some arbitrary other
# command on a list of servers. If the command starts with
# "sudo", a password is requested which will be used to get
# sudo permissions.
# The script is most useful when used with public key ssh authentication.
# You can customize the default values at the beginning of the script.
# Examples:
#   upgradebest.sh              -- Upgrade all servers
#   upgradebest.sh cluj-mx gent -- Upgrade only cluj-mx.example.com and gent.example.com
#   upgradebest.sh -c "sudo a b c" tallinn lisbon
#                               -- Execute "sudo a b c" on tallinn.example.com and lisbon.example.com
#   upgradebest.sh -e "-l username"
#                               -- Upgrade all servers, logging in as user "username"
# Author: Heinrich Moser, mail@heinzi.at
# Version: 1.2, 2007-09-03

# Default ssh_options, if no -e is given

# Default command, if no -c is given -- just upgrade the server
COMMAND="sudo aptitude -y upgrade"

# Default list of servers
SERVERS="cluj-mx gent gent-mx lisbon"

# Default suffix to add to all server names (default list and command line)

leave_usage() { # show usage message and exit with error
    echo "Usage: upgradebest.sh [-e ssh_options] [-c command] [server ...]"
    exit 1

# Parse command line arguments
while getopts ":e:c:" options; do
    case "$options" in
	'?' ) echo "Invalid option -$OPTARG"; leave_usage;;
	':' ) echo "Option -$OPTARG requires an argument."; leave_usage;;
        * ) echo "This line should never be reached."; exit 1;;
shift $(($OPTIND - 1)) # let $1 be first non-option argument

# The rest of the command line specifies the list of servers
if [ -n "$1" ]; then

# Test whether sudo is required
[[ "$COMMAND" =~ "^sudo" ]] && SUDO=yes || SUDO=no

# If sudo is performed, read password required for sudo
[ "$SUDO" = "yes" ] && read -rsp 'sudo password: ' PWD

for s in $SERVERS; do
	echo "--- Executing \"$COMMAND\" on $SERVER ---"

	# Get sudo rights (if required),
	# then connect again (with pseudo-terminal) and upgrade
	if [ "$SUDO" = "yes" ]; then
		if ! echo $PWD | \
		    ssh -o "ConnectTimeout 10" $SSH_OPTIONS $SERVER "sudo -k; sudo -v"; then
			echo "Error connecting to $SERVER!"
	ssh -to "ConnectTimeout 10" $SSH_OPTIONS $SERVER "$COMMAND" \
	    || echo "Return value: $?"


If you change anything, you can send me the changes and I will put them on this page if I like them. ;-)


You can use, modify and distribute (but not sell) this script freely.

Last update: 2007-04-14