如何与Python中的另一个程序进行交互? [英] How can I interact with another program in Python?

查看:172
本文介绍了如何与Python中的另一个程序进行交互?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个运行另一个程序的Python脚本,读取另一个程序的输出并对其进行操作.问题是该程序提示输入密码,而我不知道如何自动提供密码. (出于该脚本的目的,密码本身是否以纯文本格式存储在脚本本身中并不重要.)我想做的事情是这样的:

I want to write a Python script that runs another program, reading the output of the other program and manipulating it. The problem is that this program prompts for a password, and I cannot figure out how to supply it automatically. (For the purposes of this script, it really does not matter if the password is stored in plain-text in the script itself.) What I want to do is something like:

os.system('echo someinput | /var/local/bin/someprogram') 

这会导致某个程序给了我不需要的密码提示,也没有给我程序的输出作为返回值.可悲的是,该程序无法绕过此提示.

Which results in someprogram giving me the unwanted password prompt, and also doesn't give me the program's output as the return value. Tragically, the program does not have a way to bypass this prompt.

不幸的是,对于如何解决此问题,我也有一些限制.首先,我坚持使用Python 2.3(因此无法使用子流程模块).其次,我无法安装任何新模块(因此请不要担心).幸运的是,它不必特别便携,因此仅Linux解决方案就可以了.

Unfortunately, I also have some restrictions as to how I can go about solving this problem. First, I'm stuck with Python 2.3 (so I cannot use the subprocess module). Second, I cannot install any new modules, (so no pexpect). Fortunately, it doesn't have to be particularly portable, so a Linux-only solution is fine.

我一直在尝试找出pty模块,因为它看起来像我需要的东西,但是花了很多时间努力解决之后,我只是无法弄清楚如何使其以我需要的方式工作

I've been trying to figure out the pty module, since it looks like it offers what I need, but after spending hours wrestling with it, I just cannot figure out how to get it to work the way I need it to.

推荐答案

基于终端的进程间通信存在一些类似的问题,这些问题似乎无法使用popen解决(等).我最后通过阅读 pexpect 的源代码学习了如何使用pty,其中包含以下示例如何(以及对原因的​​评论)让pty跳过必要的障碍.

I had some similar problems with terminal-based interprocess communication that didn't seem to be solvable using popen (et al.). I ended up learning how to use pty by reading the source of pexpect, which contains examples of how (and comments of why) to get pty to jump through the necessary hoops.

当然,根据您的需求,您也可以使用 pexpect!

Depending on your needs, of course, you could also just use pexpect!

这是我在自己的项目中使用的内容.请注意,我没有检查子进程是否终止.该脚本旨在作为守护程序运行,以管理长时间运行的Java进程,因此我无需处理状态代码.希望这能为您带来大部分所需.

Here's the meat of what I used in my own project. Note that I'm not checking to see whether the child process terminates; the script was intended to run as a daemon managing a long-running Java process, so I never had to deal with status codes. Hopefully, this will get you most of what you need, however.

import os
import pty
import select
import termios

child_pid, child_fd = pty.fork()

if not child_pid: # child process
    os.execv("/path/to/command", ["command", "arg1", "arg2"])

# disable echo
attr = termios.tcgetattr(child_fd)
attr[3] = attr[3] & ~termios.ECHO
termios.tcsetattr(child_fd, termios.TCSANOW, attr)

while True:
    # check whether child terminal has output to read
    ready, _, _ = select.select([child_fd], [], [])

    if child_fd in ready:
        output = []

        try:
            while True:
                s = os.read(child_fd, 1)

                # EOF or EOL
                if not s or s == "\n":
                    break

                # don't store carriage returns (no universal line endings)
                if not s == "\r":
                    output.append(s)
        except OSError: # this signals EOF on some platforms
            pass

        if output.find("Enter password:") > -1:
            os.write(child_fd, "password")

这篇关于如何与Python中的另一个程序进行交互?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆