Python3, ssh and redirect stdout?

Once ago I got a task. It was pretty easy, as I see now. But then I didn’t know about such great thing as Ansible. So I decided to make it with python3. This post is an example of a very easy python3 program, which recursively runs a given command on hosts from a list.

Yeah, about a task. I needed to write a script which can connect to some hosts with ssh, run some command and collect an output to file. The following is a source. I think it may be useful for someone.

from subprocess import PIPE, Popen
import time
import sys
import os

REPORTDATE = time.strftime("%d.%m.%Y")
FILENAME = "report"
FILEEXT = ".txt"
FILETOWRITE = FILENAME+REPORTDATE+FILEEXT 
try:
  os.remove(FILETOWRITE)
except FileNotFoundError:
  True
sys.stdout = open(FILETOWRITE, 'w')

cmd = 'cat /etc/redhat-release'   #command to be run on remote host
FNULL = open(os.devnull, 'w')
print("Some text in report's header:")
AGENTS = ("192.168.1.10", "192.168.1.20", "192.168.1.30")   #host list
SEPARATOR = "-------------------------------------------------------"
for agent in AGENTS:
  print(agent)
  print(SEPARATOR)
  stream = Popen(['ssh', 'd.unterov@'+agent, cmd],   #your username
                   stdin=PIPE, stdout=PIPE, stderr=FNULL)
  rsp = stream.stdout.read().decode('utf-8')
  print(rsp)
  print(SEPARATOR)

sys.stdout.close() 

This script does the following, step by step:

  • Checks if old report exists
  • If exist - deletes it
  • redirects stdout to that file
  • runs a given command recursively on hosts from a list
  • closes the file

And if we print report file we’ll see something like that:

$ cat report07.08.2017.txt 
Some text in report's header:
192.168.1.10
-------------------------------------------------------
Fedora release 25 (Twenty Five)

-------------------------------------------------------
192.168.1.20
-------------------------------------------------------
Fedora release 25 (Twenty Five)

-------------------------------------------------------
192.168.1.30
-------------------------------------------------------
Fedora release 25 (Twenty Five)

-------------------------------------------------------

This was exactly what I needed. But now, of course, I use Ansible for collecting such information.

Written on August 7, 2017