Let’s update our script: ssh_cmds = ssh_cmds.append(run_ssh_cmd('', 'cmd 1')) ssh_cmds.append(run_ssh_cmd('', 'cmd 2')) while all(cmd.poll() is None for cmd in ssh_cmds): time.sleep(1) print('not done yet') print('done!') What if we don’t really care about the output of the ssh command? What if we need to run a bunch of slow commands in parallel and not wait for them to finish one by one? Using Popen we can accomplish this easily. We’ll explore how to use the pipes for output next. Next, we pass the host to connect to and the following command to run on that host.Ī Popen object is returned by this method and we set up pipes for all input and output from the underlying call. Inside this list, we call ssh and then allocate a pseudo-terminal using the -t argument. This is a bit more verbose, but safer and cleaner than simply passing an interpolated string. Using Popen we pass a list of commands and their respective arguments the cmds variable. There is a lot going on here so let’s break it down one element at a time.įirst, we pull in the required Popen and PIPE objects from subprocess, then build a simple method for running the ssh command (more about the time library later). Let’s look at how we might build a simple Python script to run an ssh command on a remote host: #!/usr/bin/env python3 import time from subprocess import Popen, PIPE def run_ssh_cmd(host, cmd): cmds = return Popen(cmds, stdout=PIPE, stderr=PIPE, stdin=PIPE) If you’re used to using a password with ssh and aren’t sure where to begin, check out this GitHub article on generating a new ssh key pair.Įnsure you can access the test hosts via ssh on the command line before proceeding with the script. This will provide access to the host via ssh without having to enter a password on the command line or store it in a file somewhere (which isn’t a great practice). Ideally, you should already have your public ssh key present in authorized_keys on these remote hosts. Getting Startedīefore we proceed it's helpful to have a test host or two ready to access via ssh. Specifically, we’ll look at using Popen to abstract the ssh system calls and make managing long-running commands much easier. In this article, we’ll explore the Subprocess library. So what is an easy, headache-free way to do this without ever leaving the comfort of Python? One of Python’s standard libraries, of course. Passing complex commands with multiple arguments to ssh inside a script will get messy fast. Many times in the past I have resorted to issuing raw system calls or attempting to just accomplish something in Bash. There are larger tools like Ansible that abstract a lot of the connection logic away, but tools like these can be overkill and take much longer to set up than just a simple script. Being able to connect to and execute commands on remote machines is where things can get a bit tricky. Solving annoying problems, collecting some basic data or running a few commands is a total breeze.
0 Comments
Leave a Reply. |