2012-10-27 79 views
1

嗨,我是Python新手。python popen()與paramiko interactive.py

我現在正在開發使用popen()方法分離ssh shell。

"Start a shell process for running commands" 
    if self.shell: 
     error("%s: shell is already running") 
     return 
     cmd = [ './sshconn.py' ] 
     self.shell = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT, 
      close_fds=True) 

     self.stdin = self.shell.stdin 
     self.stdout = self.shell.stdout 
     self.pid = self.shell.pid 
     self.pollOut = select.poll() 
     self.pollOut.register(self.stdout) 

此方法使用paramiko演示中的interactive.py代碼作爲命令。

#!/usr/bin/python 

import sys 
import paramiko 
import select 
import termios 
import tty 

def main(): 
    ssh = paramiko.SSHClient() 
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    ssh.connect('host', username='user', password='secret') 

    tran = ssh.get_transport() 
    chan = tran.open_session() 

    chan.get_pty() 
    chan.invoke_shell() 

    oldtty = termios.tcgetattr(sys.stdin) 
    try: 
      while True: 
        r, w, e = select.select([chan, sys.stdin], [], []) 
        if chan in r: 
          try: 
            x = chan.recv(1024) 
            if len(x) == 0: 
              print '\r\n*** EOF\r\n', 
              break 
            sys.stdout.write(x) 
            sys.stdout.flush() 
          except socket.timeout: 
            pass 
        if sys.stdin in r: 
          x = sys.stdin.read(1) 
          if len(x) == 0: 
            break 
          chan.send(x) 
    finally: 
      termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) 

if __name__ == '__main__': 
    main() 

問題是popen方法時()被執行,則返回 回溯(最近最後一次通話):

File "./sshconn.py", line 43, in <module> 
    main() 
File "./sshconn.py", line 20, in main 
    oldtty = termios.tcgetattr(sys.stdin) 
    termios.error: (22, 'Invalid argument') 

我該如何解決這個問題?

+2

從Python腳本運行Python文件很少有很好的理由。 '導入'該文件並在您自己的腳本中使用它的類和方法。 – Blender

回答

0

我認爲一個可能的解釋是sys.stdin未連接到TTY(它的PIPE與您的Popen一樣)。

如果你想要一個交互式shell,你應該與它交互。如果您想要一個非交互式shell,理想的解決方案是調用遠程程序並等待它返回成功或失敗的錯誤代碼。相反,嘗試使用paramiko而不是exec_command(),這更簡單。