从蟒蛇内运行交互式命令(Running an interactive command from wi

2019-06-17 11:09发布

我有我想从巨蟒(2.6.5)中运行的遵循以下逻辑的脚本:

  • 提示用户输入密码。 看起来像(“请输入密码:)”)(*注:输入不回显到屏幕)
  • 输出无关的信息
  • 为响应提示用户( “等等等等FILENAME.TXT等等等等(Y / N)?:”)

最后提示行中包含的文字,我需要解析(FILENAME.TXT)。 提供不要紧响应(程序实际上可以在这里退出,而不提供一个,只要我能解析线)

我的要求是有点类似结束语在Python脚本交互式命令行应用程序 ,但反应似乎有一点混乱,即使在OP提到,它不是做他矿仍然挂起。

经过四处寻找,我得出这样的结论subprocess是这样做的最佳方式,但我有一些问题。 这里是我的POPEN行:

p = subprocess.Popen("cmd", shell=True, stdout=subprocess.PIPE, 
stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
  • 当我调用read()readline()stdout ,提示是打印机的屏幕和它挂起。

  • 如果我所说的write("password\n")stdin ,提示被写入屏幕,它挂起。 在文中write()不写(我不移动光标的新行)。

  • 如果我叫p.communicate("password\n")相同的行为的write()

我在这里寻找一些想法的最佳方式输入到stdin和可能,如果你的大方的感觉如何解析的最后一行输出,虽然我大概可以明白这一点,最终。

Answer 1:

如果您正在使用子过程产生一个程序通信,你应该看看非阻塞读取Python中的subprocess.PIPE 。 我和我的应用程序有类似的问题,并使用队列是做一个子进程持续沟通的最佳途径找到。

至于从用户获取值,你可以随时使用的raw_input()内建得到响应,并为密码,尝试使用getpass模块来从你的用户不呼应的密码。 然后,您可以分析这些答复,并将其写入到您的子标准输入。

最后我做一个类似于如下:

import sys
import subprocess
from threading  import Thread

try:
    from Queue import Queue, Empty
except ImportError:
    from queue import Queue, Empty  # python 3.x


def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        queue.put(line)
    out.close()


def getOutput(outQueue):
    outStr = ''
    try:
        while True: #Adds output from the Queue until it is empty
            outStr+=outQueue.get_nowait()

    except Empty:
        return outStr

p = subprocess.Popen("cmd", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, universal_newlines=True)

outQueue = Queue()
errQueue = Queue()

outThread = Thread(target=enqueue_output, args=(p.stdout, outQueue))
errThread = Thread(target=enqueue_output, args=(p.stderr, errQueue))

outThread.daemon = True
errThread.daemon = True

outThread.start()
errThread.start()

try:
    someInput = raw_input("Input: ")
except NameError:
    someInput = input("Input: ")

p.stdin.write(someInput)
errors = getOutput(errQueue)
output = getOutput(outQueue)

一旦你的队列制成,并且线程开始,你可以通过从用户获取输入,得到错误和输出过程中,处理并显示给用户环路。



Answer 2:

使用线程可能是简单的任务略有矫枉过正。 相反os.spawnvpe可以使用。 这将产生脚本外壳作为一个过程。 您将可以用脚本进行交互式通信。 在这个例子中,我传递的密码作为参数,这显然是一个不好的主意。

import os
import sys
from getpass import unix_getpass

def cmd(cmd):
    cmd = cmd.split()
    code = os.spawnvpe(os.P_WAIT, cmd[0], cmd, os.environ)
    if code == 127:
        sys.stderr.write('{0}: command not found\n'.format(cmd[0]))
    return code

password = unix_getpass('Password: ')
cmd_run = './run.sh --password {0}'.format(password)
cmd(cmd_run)

pattern = raw_input('Pattern: ')
lines = []
with open('filename.txt', 'r') as fd:
    for line in fd:
        if pattern in line:
            lines.append(line)

# manipulate lines


文章来源: Running an interactive command from within python