Skip to content

Instantly share code, notes, and snippets.

@mitio
Last active August 15, 2022 00:57
Show Gist options
  • Save mitio/7154639 to your computer and use it in GitHub Desktop.
Save mitio/7154639 to your computer and use it in GitHub Desktop.
A small script to run a single command on multiple servers.

Run a command on multiple servers

A small script to allow running the same command on multiple servers. The commands are ran in series so that if you see an error somewhere, you can quickly bail out with Ctrl + C and avoid further damage to your servers.

Usage

Run as:

run-on dbserver.mysite.com frontend.mysite.com 'date; df -h /tmp'

Output:

Running the following command on 2 server(s):

date; df -h /tmp

---> Running command on dbserver.mysite.com as root:
Fri Oct 25 06:40:58 MST 2013
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1             1.1T   92G  952G   9% /tmp

---> Running command on frontend.mysite.com as root:
Fri Oct 25 06:41:02 MST 2013
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1             1.7T   88G  1.5T   6% /tmp

Installation

To install, execute the following command in one go in your shell:

mkdir -p ~/bin && \
  curl 'https://gist.github.com/mitio/7154639/raw/run-on' > ~/bin/run-on && \
  chmod a+rx ~/bin/run-on

If ~/bin is in your $PATH, you'll be able to use run-on directly. Otherwise, type ~/bin/run-on.

#!/bin/bash
if [ $# = 0 ]
then
self=`basename $0`
echo "Execute a command on multiple servers."
echo
echo "1. Basic Usage"
echo
echo " $self server1 [server2 ...] command"
echo
echo "2. Command"
echo
echo " Keep in mind that the command you want to run should be the last argument"
echo " and should be in single or double quotes."
echo
echo "3. Remote User"
echo
echo " The commands are ran as root. If you want to run them as another user, use:"
echo
echo " user=www-data $self server1 [server2 ...] command"
echo
echo "3. Common Domains"
echo
echo " If all servers are under the same domain, you can set a domain variable and"
echo " provide only the subdomain parts to the $self command, like so:"
echo
echo " domain=example.org $self s01 s02 s03 command"
echo
echo " The command will be run on s01.example.org, s02.example.org, and so on."
exit 1
fi
command="${@: -1}"
servers_count=$(($# - 1))
servers="${@:1:$servers_count}"
user=${user:-root}
if [ -n "$domain" ]
then
domain=".$domain"
else
domain=""
fi
if [ -z "$command" ]
then
echo "Please provide a command to run as the last argument (in quotes)."
exit 2
fi
if [ -z "$servers" ]
then
echo "Please provide at least one server name to run the command on."
exit 3
fi
echo "Running the following command on $servers_count server(s):"
echo
echo $command
echo
for server in $servers
do
hostname="$server$domain"
echo "---> Running command on $hostname as $user:"
ssh $user@$hostname "$command"
echo
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment