在 Python 内部运行交互式命令

2025-04-10 09:45:00
admin
原创
20
摘要:问题描述:我有一个脚本,想要在 Python(2.6.5)中运行,该脚本遵循以下逻辑:提示用户输入密码。它看起来像(“输入密码:”)(*注意:输入不会回显到屏幕上)输出不相关的信息提示用户回应(“Blah Blah filename.txt blah blah (Y/N)?:”)最后一行提示包含我需要解析的文...

问题描述:

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

  • 提示用户输入密码。它看起来像(“输入密码:”)(*注意:输入不会回显到屏幕上)

  • 输出不相关的信息

  • 提示用户回应(“Blah Blah filename.txt blah blah (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
    ")for stdin,提示会写入屏幕并挂起。 中的文本write()`不会写入(我不会将光标移到新行)。

  • 如果我调用`p.communicate("password
    ")`,行为与 write() 相同

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


解决方案 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)

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

解决方案 2:

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

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
'.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
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用