首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从Python中运行交互式命令

从Python中运行交互式命令
EN

Stack Overflow用户
提问于 2012-07-13 02:07:13
回答 2查看 39.8K关注 0票数 20

我有一个脚本,我想从Python (2.6.5)中运行,它遵循以下逻辑:

  • 会提示用户输入密码。它看起来像("Enter password:") (*注意:输入不会回显到屏幕),输出与用户无关的information
  • Prompt

用户响应("Blah

  • Blah blah (Y/N)?:")

最后一个提示行包含我需要解析的文本(filename.txt)。提供的响应并不重要(程序实际上可以在不提供响应的情况下退出,只要我可以解析这行代码)。

我的需求有点类似于,但那里的响应似乎有点令人困惑,即使操作员提到它不适合他,我的也仍然挂起。

通过环顾四周,我得出结论,subprocess是做这件事的最好方法,但我有一些问题。这是我的Popen行:

代码语言:javascript
复制
p = subprocess.Popen("cmd", shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

  • 当我在stdout上调用read()readline()时,提示是printer to screen,它挂起。

  • 如果我调用stdinwrite("password\n"),提示符就会写入屏幕并挂起。write()中的文本未写入(我不会将光标移动到新行)。

  • 如果我调用p.communicate("password\n"),则行为与

的write()相同

我在这里寻找一些关于输入到stdin的最佳方式的想法,以及如果您觉得慷慨的话,可能如何解析输出中的最后一行,尽管我最终可能会弄清楚。

EN

回答 2

Stack Overflow用户

发布于 2012-11-20 00:51:58

如果您正在与一个子进程派生的程序通信,您应该查看。我的应用程序遇到了类似的问题,我发现使用队列是与子进程进行持续通信的最佳方式。

至于从用户获取值,您可以始终使用raw_input()内置函数来获取响应,而对于密码,可以尝试使用getpass模块从用户那里获取非回显密码。然后,您可以解析这些响应并将它们写入子进程的stdin。

我最终做了类似于下面的事情:

代码语言:javascript
复制
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)

一旦创建了队列并启动了线程,就可以循环从用户获取输入,从进程获取错误和输出,然后处理它们并将它们显示给用户。

票数 15
EN

Stack Overflow用户

发布于 2015-04-07 04:41:16

对于简单的任务,使用线程可能有点夸大其词。相反,可以使用os.spawnvpe。它会将脚本shell作为一个进程生成。您将能够与脚本进行交互通信。在本例中,我传递了password作为参数,显然这不是一个好主意。

代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11457931

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档