Python subprocess – run multiple shell commands over SSH

Question:

I am trying to open an SSH pipe from one Linux box to another, run a few shell commands, and then close the SSH.

I don’t have control over the packages on either box, so something like fabric or paramiko is out of the question.

I have had luck using the following code to run one bash command, in this case “uptime”, but am not sure how to issue one command after another. I’m expecting something like:

sshProcess = subprocess.call('ssh ' + <remote client>, <subprocess stuff>)
lsProcess = subprocess.call('ls', <subprocess stuff>)
lsProcess.close()
uptimeProcess = subprocess.call('uptime', <subprocess stuff>)
uptimeProcess.close()
sshProcess.close()

What part of the subprocess module am I missing?

Thanks

pingtest = subprocess.call("ping -c 1 %s" % <remote client>,shell=True,stdout=open('/dev/null', 'w'),stderr=subprocess.STDOUT)
if pingtest == 0:
  print '%s: is alive' % <remote client>
  # Uptime + CPU Load averages
  print 'Attempting to get uptime...'
  sshProcess = subprocess.Popen('ssh '+<remote client>, shell=True,stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  sshProcess,stderr = sshProcess.communicate()
  print sshProcess
  uptime = subprocess.Popen('uptime', shell=True,stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  uptimeProcess,stderr = uptimeProcess.communicate()
  uptimeProcess.close( )
  print 'Uptime         : ' + uptimeProcess.split('up ')[1].split(',')[0]
else:
  print "%s: did not respond" % <remote client>
Asked By: user2978190

||

Answers:

basically if you call subprocess it creates a local subprocess not a remote one
so you should interact with the ssh process. so something along this lines:
but be aware that if you dynamically construct my directory it is suceptible of shell injection then END line should be a unique identifier
To avoid the uniqueness of END line problem, an easiest way would be to use different ssh command

from __future__ import print_function,unicode_literals
import subprocess

sshProcess = subprocess.Popen(['ssh',
                               '-tt'
                               <remote client>],
                               stdin=subprocess.PIPE, 
                               stdout = subprocess.PIPE,
                               universal_newlines=True,
                               bufsize=0)
sshProcess.stdin.write("ls .n")
sshProcess.stdin.write("echo ENDn")
sshProcess.stdin.write("uptimen")
sshProcess.stdin.write("logoutn")
sshProcess.stdin.close()


for line in sshProcess.stdout:
    if line == "ENDn":
        break
    print(line,end="")

#to catch the lines up to logout
for line in  sshProcess.stdout: 
    print(line,end="")
Answered By: Xavier Combelle
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.