2011-03-07 124 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化」。

相關問題