Hi I’m newbie in python.
I am now developing detaching ssh shell using popen() method.
"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 )
And this method uses interactive.py code in paramiko’s demo as command.
#!/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()
The problem is when popen() is executed, it returns
Traceback (most recent call last):
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')
How can I solve this?
I think a likely explanation is that
sys.stdinis not connected to a TTY (it’s aPIPEas in yourPopen).If you want an interactive shell, you should interact with it. If you want a non-interactive shell, the ideal solution is to invoke a remote program and wait for it to return an error code of success or failure. Try using
paramikoto merelyexec_command()instead, it’s much simpler.