2

Hello All i'm stuck with a small problem. May be i'm missing something obvious but i'm unable to figure out the problem. I've GUI where i have a button named "erp" and if i press that it should do an ssh first to a machine named (host id name) 'ayaancritbowh91302xy' and then it should execute commands like (cd change dir) and 'ls -l'. I've tried the following code:

def erptool():
    sshProcess = subprocess.Popen(['ssh -T', 'ayaancritbowh91302xy'],stdin=subprocess.PIPE, stdout = subprocess.PIPE)
    sshProcess.stdin.write("cd /home/thvajra/transfer/08_sagarwa\n")
    sshProcess.stdin.write("ls -l\n")
    sshProcess.stdin.write("echo END\n")
    for line in stdout.readlines():
        if line == "END\n":
        break
        print(line)

i got the following error:

Traceback (most recent call last):
  File "Cae_Selector.py", line 34, in erptool
    for line in stdout.readlines():
NameError: global name 'stdout' is not defined
Pseudo-terminal will not be allocated because stdin is not a terminal.

How to do this? can anyone help me with this?

ayaan
  • 715
  • 5
  • 18
  • 36
  • 1
    start by fixing the stdout error: try adding "from sys import stdout" or change it to sshProcess.stdout if that's what you mean. – Nick Russo Oct 07 '14 at 02:45
  • consider adding a '-T' after 'ssh', so that ssh won't even try to allocate a pseudo-terminal. – Nick Russo Oct 07 '14 at 02:45
  • i used '-t' after ssh now i got the following error: File "Cae_Selector.py", line 35, in erptool for line in stdout.readlines(): IOError: File not open for reading usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q cipher | cipher-auth | mac | kex | ke – ayaan Oct 07 '14 at 02:50
  • sorry -- it's capital T – Nick Russo Oct 07 '14 at 02:51
  • 1
    @ayaan If you want to keep the ssh process open in the background, don't use `communicate` but take a look at the accepted answer for http://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in-python – metatoaster Oct 07 '14 at 03:41
  • it helped a lot @metatoaster – ayaan Oct 07 '14 at 04:16

3 Answers3

4

Try this:

#!/usr/bin/env python
import subprocess
def erptool():
    sshProcess = subprocess.Popen(['ssh', '-T', 'ayaancritbowh91302xy'],
                                  stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    out, err = sshProcess.communicate("cd /home/thvajra/transfer/08_sagarwa\nls -l\n")
    print(out),
erptool()

I added -T so ssh wouldn't try to allocate a pseudo-tty, and avoid END and stdout issues by using communicate.

Nick Russo
  • 1,522
  • 10
  • 13
3

To execute several shell commands via ssh:

#!/usr/bin/env python3
from subprocess import Popen, PIPE

with Popen(['ssh', '-T', 'ayaancritbowh91302xy'],
           stdin=PIPE, stdout=PIPE, stderr=PIPE,
           universal_newlines=True) as p:
    output, error = p.communicate("""            
        cd /home/thvajra/transfer/08_sagarwa
        ls -l
        """)
    print(output)
    print(error)
    print(p.returncode)

output contains stdout, error -- stderr, p.returncode -- exit status.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • so if i want to open a software will this method work@J.F.Sebastian – ayaan Oct 07 '14 at 03:12
  • @ayaan: it depends on software. Your comment to the other answer suggests that you want to run matlab, see [Run Matlab in Linux without graphical environment?](http://stackoverflow.com/q/11046470/4279): try `matlab -nodesktop`. If it doesn't work, [update your question](http://stackoverflow.com/posts/26227791/edit) or [ask a new one](http://stackoverflow.com/questions/ask). – jfs Oct 07 '14 at 03:18
0

It must be sshProcess.stdout.readLines() as you are talking to the process's stdout....