2

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

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

这导致 someprogram 给了我不需要的密码提示,也没有给我程序的输出作为返回值。可悲的是,程序没有办法绕过这个提示。

不幸的是,我对如何解决这个问题也有一些限制。首先,我坚持使用 Python 2.3(所以我不能使用 subprocess 模块)。其次,我无法安装任何新模块,(所以没有预期)。幸运的是,它不必特别便携,因此仅 Linux 的解决方案就可以了。

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

4

3 回答 3

3

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")
于 2011-03-07T22:10:22.100 回答
0

您可以使用os.popen,它已在 2.6 中移至,subprocess但仍应存在于 2.3 的os模块中。将模式设置为'w'并用于close()获取返回值。

于 2011-03-07T21:53:41.867 回答
0

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

这些模块的主要目标是使处理子流程(例如您所描述的)更容易且更“Pythonic”。

于 2011-03-08T06:46:33.440 回答