使用 os.forkpty() 创建一个伪终端以 ssh 到远程服务器并与其通信

发布于 2024-12-01 04:13:45 字数 781 浏览 0 评论 0原文

我正在尝试编写一个 python 脚本,它可以 ssh 到远程服务器,并可以从 python 客户端执行 ls,cd 等简单命令。但是,在成功 ssh 到服务器后,我无法读取伪终端的输出。任何人都可以在这里帮助我,以便我可以在服务器上执行一些命令。

这是示例代码:

#!/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

示例输出:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海螺姑娘 2024-12-08 04:13:45

我建议尝试模块 pexpect,它是专门为此类事情构建的(通过伪 TTY 与其他应用程序交互),或者 Fabric,它是为此类事情更抽象地构建的(自动化远程服务器上的系统管理任务)使用 SSH)。

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

结构:http://docs.fabfile.org/en/1.11/

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/

怼怹恏 2024-12-08 04:13:45

如前所述,最好使用公钥。当我正常使用它们时,我已经更改了你的程序,以便它在这里工作。

#!/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

通过添加 sleep(1),我给远程主机(或者,在我的例子中,不是那么远程的主机)有时间处理 ls 命令并生成其输出。

如果您发送ls并立即阅读,您只会阅读当前存在的内容。也许你应该循环阅读。

或者你应该这样做:

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

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文