我如何与Python中的另一个程序进行交互?

我想编写一个运行另一个程序的Python脚本,读取其他程序的输出并对其进行处理。 问题是这个程序提示input密码,我不知道如何自动提供。 (对于这个脚本来说,如果密码是以纯文本的forms存储在脚本本身,那真的没什么关系)。我想要做的就是:

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

这会导致某些程序给我不需要的密码提示,也不会将程序的输出作为返回值。 不幸的是,该scheme没有办法绕过这个提示。

不幸的是,我对于如何解决这个问题也有一些限制。 首先,我坚持Python 2.3(所以我不能使用subprocess模块)。 其次,我不能安装任何新的模块,(所以没有关系)。 幸运的是,它不必特别便携,所以只有Linux的解决scheme是好的。

我一直在试图弄清楚pty模块,因为它看起来像提供了我所需要的,但花了几个小时的时间与之搏斗后,我无法弄清楚如何让它按我需要的方式工作。

Solutions Collecting From Web of "我如何与Python中的另一个程序进行交互?"

我有一些类似的基于终端的进程间通信的问题,似乎不能用popen (et al。)解决。 我最终学习了如何使用pty通过阅读pexpect的源代码 ,其中包含如何(以及为什么要评论)让pty跳过必要的环节的例子。

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

这是我在自己的项目中使用的肉。 请注意,我没有检查子进程是否终止; 该脚本旨在作为管理长期运行的Java进程的守护进程运行,所以我从来不必处理状态代码。 但是,希望这会使你获得所需的大部分。

 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") 

你可以使用os.popen ,它在2.6中被移动到了subprocess 进程中 ,但是仍然应该存在于2.3的os模块中。 将模式设置为'w'并使用close()来获取返回值。

还有另一个expect Python实现,很容易支持pty的。 有一个包装ssh的库,可以使用它发送密码。 这是Pycopia中的sshlib模块 。 那里有一个处理密码的登录方法。 它使用Pycopia的expect和process(proctools)模块。 我最初是为Python 2.2写的,所以他们可能会为你工作。 但是,他们可能没有,因为我已经随着时间的推移自由地使用了Python的其他新功能,可能已经悄悄进入。

这些模块的主要目标是处理子流程,比如你所描述的,更容易和更“pythonic”。