Using os.forkpty() to create a pseudo-terminal to ssh to a remote server and communicate with it

社会主义新天地 提交于 2019-12-22 07:23:05

问题


I'm trying to write a python script that can ssh into remote server and can execute simple commands like ls,cd from the python client. However, I'm not able to read the output from the pseudo-terminal after successfully ssh'ing into the server. Could anyone please help me here so that I could execute some commands on the server.

Here is the sample code:

#!/usr/bin/python2.6
import os,sys,time,thread
pid,fd = os.forkpty()
if pid == 0:
    os.execv('/usr/bin/ssh',['/usr/bin/ssh','user@host',])
    sys.exit(0)
else:
    output = os.read(fd,1024)
    print output
    data = output
    os.write(fd,'password\n')
    time.sleep(1)
    output = os.read(fd,1024)
    print output
    os.write(fd,'ls\n')
    output = os.read(fd,1024)
    print output

Sample output:

user@host's password: 

Last login: Wed Aug 24 03:16:57 2011 from 1x.x.x.xxxx

-bash: ulimit: open files: cannot modify limit: Operation not permitted
host: /home/user>ls

回答1:


I'd suggest trying the module pexpect, which is built exactly for this sort of thing (interfacing with other applications via pseudo-TTYs), or Fabric, which is built for this sort of thing more abstractly (automating system administration tasks on remote servers using SSH).

pexpect: http://pypi.python.org/pypi/pexpect/

Fabric: http://docs.fabfile.org/en/1.11/




回答2:


As already stated, better use public keys. As I use them normally, I have changed your program so that it works here.

#!/usr/bin/python2.6
import os,sys,time,thread
pid,fd = os.forkpty()
if pid == 0:
    os.execv('/usr/bin/ssh',['/usr/bin/ssh','localhost',])
    sys.exit(0)
else:
    output = os.read(fd,1024)
    print output
    os.write(fd,'ls\n')
    time.sleep(1) # this is new!
    output = os.read(fd,1024)
    print output

With the added sleep(1), I give the remote host (or, in my case, not-so-remote host) time to process the ls command and produce its output.

If you send ls and read immediately, you only read what is currently present. Maybe you should read in a loop or so.

Or you just should do it this way:

import subprocess
sp = subprocess.Popen(("ssh", "localhost", "ls"), stdout=subprocess.PIPE)
print sp.stdout.read()


来源:https://stackoverflow.com/questions/7173878/using-os-forkpty-to-create-a-pseudo-terminal-to-ssh-to-a-remote-server-and-com

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!