First, make sure that
parallel-ssh is installed.
Run a command on hosts in parallel
The most basic usage of
parallel-ssh is, unsurprisingly, to run a command on multiple hosts in parallel.
A complete example is shown below.
Examples all assume a valid key is available on a running SSH agent. See Programmatic Private Key Authentication for authenticating without an SSH agent.
Host list can contain identical hosts. Commands are executed concurrently on every host given to the client regardless, up to pool size.
from pssh.clients import ParallelSSHClient hosts = ['localhost', 'localhost', 'localhost', 'localhost'] client = ParallelSSHClient(hosts) cmd = 'uname' output = client.run_command(cmd) for host_out in output: for line in host_out.stdout: print(line)
Linux Linux Linux Linux
Single Host Client
parallel-ssh has a fully featured, asynchronous single host client that it uses for all its parallel commands.
Users that do not need the parallel capabilities can use the single host client for a simpler way to run asynchronous non-blocking commands on a remote host.
from pssh.clients import SSHClient host = 'localhost' cmd = 'uname' client = SSHClient(host) host_out = client.run_command(cmd) for line in host_out.stdout: print(line)
Step by Step
Make a list or other iterable of the hosts to run on:
from pssh.clients import ParallelSSHClient hosts = ['host1', 'host2', 'host3', 'host4']
host4 are valid host names. IP addresses may also be used.
Create a client for these hosts:
client = ParallelSSHClient(hosts)
The client object can, and should, be reused. Existing connections to hosts will remain alive as long as the client object is kept alive. Subsequent commands to the same host(s) will reuse their existing connection and benefit from much faster response times.
Now one or more commands can be run via the client:
output = client.run_command('uname')
When the call to
run_command returns, the remote commands are already executing in parallel.
Run Command Output
Standard output, aka
stdout, for a given
for line in host_out.stdout: print(line)
<line by line output> <line by line output> <..>
stdout will only end when the remote command has finished unless interrupted.
read_timeout keyword argument to
run_command may be used to cause reading to timeout if no output is received after the given number of seconds - see join and output timeouts.
stdout is a generator. To retrieve all of stdout can wrap it with list, per below.
stdout = list(host_out.stdout)
All hosts iteration
Of course, iterating over all hosts can also be done the same way.
for host_output in output: for line in host_output.stdout: print("Host [%s] - %s" % (host, line))
from pssh.clients import ParallelSSHClient client = ParallelSSHClient(['localhost', 'localhost']) output = client.run_command('whoami') client.join() for host_output in output: hostname = host_output.host stdout = list(host_output.stdout) print("Host %s: exit code %s, output %s" % ( hostname, host_output.exit_code, stdout))
localhost: exit code 0, stdout ['<username>'] localhost: exit code 0, stdout ['<username>']
New in 1.10.0
Exit codes are available on the host output object as a dynamic property. Exit code will be
None if not available, or the exit code as reported by channel.
First, ensure that all commands have finished by either joining on the output object or gathering all output, then iterate over all host’s output to print their exit codes.
client.join(output) for host_output in output: print("Host %s exit code: %s" % (host_output.host, host_output.exit_code))
client.join is not required as long as output has been gathered.
for host_out in output: for line in host_out.stdout: print(line) print(host_out.exit_code)
Host output class documentation.
parallel-ssh will use an available SSH agent’s credentials to login to hosts via public key authentication.
User/password authentication can be used by providing user name and password credentials:
client = ParallelSSHClient(hosts, user='my_user', password='my_pass')
On Posix platforms, user name defaults to the current user if not provided.
On Windows, user name is required.
Programmatic Private Key authentication
It is also possible to programmatically provide a private key for authentication.
from pssh.clients import ParallelSSHClient client = ParallelSSHClient(hosts, pkey='my_pkey')
my_pkey is a private key file in the current directory.
To use files under a user’s
client = ParallelSSHClient(hosts, pkey='~/.ssh/my_pkey')
Output for Last Executed Commands
Output for last executed commands can be retrieved by
client.run_command('uname') output = client.get_last_output() for host_output in output: for line in host_output.stdout: print(line)
This function can also be used to retrieve output for previously executed commands in the case where output object was not stored or is no longer available.
New in 1.2.0
There is a built in host logger that can be enabled to automatically log standard output from remote hosts. This requires the
consume_output=True flag on
The helper function
pssh.utils.enable_host_logger() will enable host logging to standard output, for example:
from pssh.utils import enable_host_logger enable_host_logger() client.run_command('uname') client.join(consume_output=True)
Using standard input
Along with standard output and error, input is also available on the host output object. It can be used to send input to the remote host where required, for example password prompts or any other prompt requiring user input.
stdin attribute on
HostOutput is a file-like object giving access to the remote stdin channel that can be written to:
output = client.run_command('read line; echo $line') host_output = output stdin = host_output.stdin stdin.write("writing to stdin\n") stdin.flush() for line in host_output.stdout: print(line)
writing to stdin
Errors and Exceptions
parallel-ssh will raise exception on any errors connecting to hosts, whether that be connection errors such as DNS resolution failure or unreachable host, SSH authentication failures or any other errors.
stop_on_errors flag is provided to tell the client to go ahead and attempt the command(s) anyway and return output for all hosts, including the exception on any hosts that failed:
output = client.run_command('whoami', stop_on_errors=False)
With this flag, the
exception output attribute will contain the exception on any failed hosts, or
client.join(output) for host_output in output: host = host_output.host print("Host %s: exit code %s, exception %s" % ( host, host_output.exit_code, host_output.exception))
Host host1: exit code 0, exception None Host host2: exit code None, exception AuthenticationError <..>
Exceptions raised by the library can be found in the
pssh.exceptions module and in API documentation.