How to use parallel ssh (PSSH) for executing ssh in parallel on a number of Linux/Unix/BSD servers

last updated in Categories Cloud Computing, Command Line Hacks, Howto

Recently I come across a nice little nifty tool called pssh to run a single command on multiple Linux / UNIX / BSD servers. You can easily increase your productivy with this SSH tool.

More about pssh

pssh is a command line tool for executing ssh in parallel on some hosts. It specialties includes:

  1. Sending input to all of the processes
  2. Inputting a password to ssh
  3. Saving output to files
  4. IT/sysadmin taks automation such as patching servers
  5. Timing out and more

Let us see how to install and use pssh on Linux and Unix-like system.

pssh-welcome

Installation

You can install pssh as per your Linux and Unix variant. Once package installed, you can get parallel versions of the openssh tools. Included in the installation:

  1. Parallel ssh (pssh command)
  2. Parallel scp (pscp command )
  3. Parallel rsync (prsync command)
  4. Parallel nuke (pnuke command)
  5. Parallel slurp (pslurp command)

Install pssh on Debian/Ubuntu Linux

Type the following apt-get command/apt command to install pssh:
$ sudo apt install pssh
OR
$ sudo apt-get install pssh
Sample outputs:

Fig.01: Installing pssh on Debian/Ubuntu Linux
Fig.01: Installing pssh on Debian/Ubuntu Linux

Install pssh on Apple MacOS X

Type the following brew command:
$ brew install pssh
Sample outputs:

Fig.02: Installing pssh on MacOS Unix
Fig.02: Installing pssh on MacOS Unix

Install pssh on FreeBSD unix

Type any one of the command:
# cd /usr/ports/security/pssh/ && make install clean
OR
# pkg install pssh
Sample outputs:

Fig.03: Installing pssh on FreeBSD
Fig.03: Installing pssh on FreeBSD

Install pssh on RHEL/CentOS/Fedora Linux

First turn on EPEL repo and type the following command yum command:
$ sudo yum install pssh
Sample outputs:

Fig.04: Installing pssh on RHEL/CentOS/Red Hat Enterprise Linux
Fig.04: Installing pssh on RHEL/CentOS/Red Hat Enterprise Linux

Install pssh on Fedora Linux

Type the following dnf command:
$ sudo dnf install pssh
Sample outputs:

Fig.05: Installing pssh on Fedora
Fig.05: Installing pssh on Fedora

Install pssh on Arch Linux

Type the following command:
$ sudo pacman -S python-pip
$ pip install pssh

How to use pssh command

First you need to create a text file called hosts file from which pssh read hosts names. The syntax is pretty simple. Each line in the host file are of the form [user@]host[:port] and can include blank lines and comments lines beginning with “#”. Here is my sample file named ~/.pssh_hosts_files:
$ cat ~/.pssh_hosts_files
vivek@dellm6700
root@192.168.2.30
root@192.168.2.45
root@192.168.2.46

Run the date command all hosts:
$ pssh -i -h ~/.pssh_hosts_files date
Sample outputs:

[1] 18:10:10 [SUCCESS] root@192.168.2.46
Sun Feb 26 18:10:10 IST 2017
[2] 18:10:10 [SUCCESS] vivek@dellm6700
Sun Feb 26 18:10:10 IST 2017
[3] 18:10:10 [SUCCESS] root@192.168.2.45
Sun Feb 26 18:10:10 IST 2017
[4] 18:10:10 [SUCCESS] root@192.168.2.30
Sun Feb 26 18:10:10 IST 2017

Run the uptime command on each host:
$ pssh -i -h ~/.pssh_hosts_files uptime
Sample outputs:

[1] 18:11:15 [SUCCESS] root@192.168.2.45
 18:11:15 up  2:29,  0 users,  load average: 0.00, 0.00, 0.00
[2] 18:11:15 [SUCCESS] vivek@dellm6700
 18:11:15 up 19:06,  0 users,  load average: 0.13, 0.25, 0.27
[3] 18:11:15 [SUCCESS] root@192.168.2.46
 18:11:15 up  1:55,  0 users,  load average: 0.00, 0.00, 0.00
[4] 18:11:15 [SUCCESS] root@192.168.2.30
 6:11PM  up 1 day, 21:38, 0 users, load averages: 0.12, 0.14, 0.09

You can now automate common sysadmin tasks such as patching all servers:
$ pssh -h ~/.pssh_hosts_files -- sudo yum -y update
OR
$ pssh -h ~/.pssh_hosts_files -- sudo apt-get -y update
$ pssh -h ~/.pssh_hosts_files -- sudo apt-get -y upgrade

How do I use pssh to copy file to all servers?

The syntax is:
pscp -h ~/.pssh_hosts_files src dest
To copy $HOME/demo.txt to /tmp/ on all servers, enter:
$ pscp -h ~/.pssh_hosts_files $HOME/demo.txt /tmp/
Sample outputs:

[1] 18:17:35 [SUCCESS] vivek@dellm6700
[2] 18:17:35 [SUCCESS] root@192.168.2.45
[3] 18:17:35 [SUCCESS] root@192.168.2.46
[4] 18:17:35 [SUCCESS] root@192.168.2.30

Or use the prsync command for efficient copying of files:
$ prsync -h ~/.pssh_hosts_files /etc/passwd /tmp/
$ prsync -h ~/.pssh_hosts_files *.html /var/www/html/

How do I kill processes in parallel on a number of hosts?

Use the pnuke command for killing processes in parallel on a number of hosts. The syntax is:
$ pnuke -h .pssh_hosts_files process_name
### kill nginx and firefox on hosts:
$ pnuke -h ~/.pssh_hosts_files firefox
$ pnuke -h ~/.pssh_hosts_files nginx

See pssh/pscp command man pages for more information.

Conclusion

pssh is a pretty good tool for parallel SSH command execution on many servers. It quite is useful if you have 5 or 10 servers. Nevertheless, if you need to do something complicated you should look into Ansible and co.

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.

Share this on (or read 5 comments/add one below):

5 comment

  1. from "violent python"
    
    #!./env/bin/python
    
    """ SSH Botnet
    
        This script logs into several different machines with ssh and sends
        commands to each of them in tandem
    
        Don't be a moron, please don't use this for something illegal.
    
        Usage:
            ssh_botnet.py
            ssh_botnet.py (-h | --help)
            ssh_botnet.py (-v | --version)
    
        Options:
            -h --help       Show this screen.
            --version       Show version
    """
    
    import pxssh
    from docopt import docopt
    from colorama import Fore, init
    
    
    class Client:
        def __init__(self, host, user, password):
            self.host = host
            self.user = user
            self.password = password
            self.session = self.connect()
    
        def connect(self):
            try:
                ssh = pxssh.pxssh()
                ssh.login(self.host, self.user, self.password)
    
                return ssh
            except Exception, e:
                print Fore.RED + '[-] Error Connecting' + Fore.RESET
                print e
    
        def send_command(self, cmd):
            self.session.sendline(cmd)
            self.session.prompt()
    
            return self.session.before
    
    
    def botnet_command(command, botnet):
        for client in botnet:
            output = client.send_command(command)
            print Fore.GREEN + '[*] Output from ' + client.host + Fore.RESET
            print '[+] ' + output + '\n'
    
    
    def add_client(host, user, password, botnet):
        client = Client(host, user, password)
        botnet.append(client)
    
    
    def main():
        botnet = []
    
        add_client('10.10.10.110', 'root', 'toor', botnet)
        add_client('10.10.10.120', 'root', 'toor', botnet)
        add_client('10.10.10.130', 'root', 'toor', botnet)
        botnet_command('uname -v', botnet)
    
    
    if __name__ == '__main__':
        init()
        docopt(__doc__, version=0.1)
        main()
    
  2. Neat utility ! I have used a similar utility in the past, called pdsh.
    Not sure about other flavours, but apt installs the parallel-ssh binary and not pssh – one can always create a link, though
    Thanks !

Comments are closed.