2011-03-07 75 views
2

我想写运行另一个程序,阅读其他程序的输出和操纵它的Python脚本。问题是这个程序会提示输入密码,我不知道如何自动提供密码。 (对于这个脚本的目的,真的没有,如果密码存储在脚本本身的纯文本问题)。我想要做的是一样的东西:我如何与Python中的其他程序进行交互?

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

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

不幸的是,我也有一些限制,我怎么能去解决这个问题。首先,我坚持使用Python 2.3(所以我不能使用子进程模块)。其次,我不能安装任何新的模块,(所以没有特别之处)。幸运的是,它不必特别便携,所以只有Linux的解决方案没问题。

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

回答

3

我与基于终端的进程间通信,这似乎不是可解使用popen一些类似的问题(等人)中。我结束了学习如何通过阅读pexpect源,其中包含(和为什么评论)获得pty通过必要跳火圈的例子如何使用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") 
+0

这是一堆很好的代码来挖掘(但相信我,我打算)。是否有机会在此发布重要摘要? – user648855 2011-03-07 22:26:44

+0

我会,但在工作时无法使用该机器。如果您可以等待大约五个小时(对不起),我很乐意在回家时发布一些示例。 – 2011-03-07 22:31:48

+0

对不起!忘了发布此更早。 – 2011-03-08 07:09:13

0

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

+0

使用你的建议,我尝试下面的代码: F = os.popen( '回声someinput |在/ var/local/bin目录/ someprogram', 'W') f.write( “密码\ n”) 但是,问题依然存在。它与tty交互,绕过stdin,看起来像。 – user648855 2011-03-07 22:06:35

+0

@ user648855:很奇怪。 – nmichaels 2011-03-08 14:22:04

0

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

这些模块的主要目标是处理子流程,比如你描述的,更简单,更“ Python化”。

相关问题