How to use parallel ssh (PSSH) for executing commands 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 parallel ssh (PSSH) to run a single command on multiple Linux / UNIX / BSD servers. You can easily increase your productive with this SSH IT automation tool.

Advertisements

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 task automation such as patching servers or looking for error logs
  5. Timing out and more

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

parallel ssh (PSSH)

parallel ssh (PSSH) 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. pssh command – Parallel ssh
  2. pscp command – Parallel scp
  3. prsync command – Parallel rsync
  4. pnuke command – Parallel nuke
  5. pslurp command – Parallel slurp

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:

Install pssh to execute commands on multiple remote Linux and Unix servers
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

Set passwordless SSH using public-private key pairs

It is recommend that you set up ssh keys for automation. To generate a key pair run the ssh-keygen command:
ssh-keygen
Next transfer the public key to the remote host using the ssh-copy-id command:
ssh-copy-id user@server-ip
ssh-copy-id vivek@dellm6700
ssh-copy-id root@192.168.2.30
ssh-copy-id root@192.168.2.45
ssh-copy-id root@192.168.2.46

Test it using the ssh command:
ssh vivek@dellm6700
ssh root@192.168.2.30

See my previous tutorials SSH Public Key Based Authentication on a Linux/Unix server and set up SSH Keys on a Linux / Unix System for more information on passwordless SSH topics.

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 the 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 7 servers or VMs. Nevertheless, if you need to do something complicated you should look into Ansible and co. See the official site here for more info.

ADVERTISEMENTS

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.

Start the discussion at www.nixcraft.com

Historical Comment Archive

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 !

    Still, have a question? Get help on our forum!