从Python内部运行交互式命令

从Python内部运行交互式命令

本文介绍了从Python内部运行交互式命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a script that I want to run from within Python (2.6.5) that follows the logic below:

  • 提示用户输入密码.看起来像(输入密码:")(*注意:输入内容不会回显到屏幕上)
  • 输出无关信息
  • 提示用户进行响应("Blah Blah filename.txt blah blah(Y/N)?:")

最后一个提示行包含我需要解析的文本(filename.txt).所提供的响应无关紧要(只要我可以解析该行,该程序实际上就可以在不提供该响应的情况下退出此处).

The last prompt line contains text which I need to parse (filename.txt). The response provided doesn't matter (the program could actually exit here without providing one, as long as I can parse the line).

我的要求有点 ,但是那里的响应似乎有些混乱,即使OP提到它不适合,我的仍然挂起他.

My requirements are somewhat similar to Wrapping an interactive command line application in a Python script, but the responses there seem a bit confusing, and mine still hangs even when the OP mentions that it doesn't for him.

通过环顾四周,我得出的结论是subprocess是执行此操作的最佳方法,但是我遇到了一些问题.这是我的Popen行:

Through looking around, I've come to the conclusion that subprocess is the best way of doing this, but I'm having a few issues. Here is my Popen line:

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

  • 当我在stdout上调用read()readline()时,提示是打印机到屏幕上并且挂起.

    • When I call a read() or readline() on stdout, the prompt is printer to the screen and it hangs.

      如果我为stdin调用write("password\n"),则提示将写入屏幕并挂起. write()中的文本未写入(我不将光标移至新行).

      If I call a write("password\n") for stdin, the prompt is written to the screen and it hangs. The text in write() is not written (I don't the cursor move the a new line).

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

      If I call p.communicate("password\n"), same behavior as write()

      我正在这里寻找有关输入stdin的最佳方法的一些想法,如果您愿意的话,可能会如何解析输出的最后一行,尽管我最终可能会发现.

      I was looking for a few ideas here on the best way to input to stdin and possibly how to parse the last line in the output if your feeling generous, though I could probably figure that out eventually.

      推荐答案

      如果与正在产生子流程的程序进行通信,则应签出 .我的应用程序遇到类似的问题,发现使用 queues 是与子流程进行持续通信的最佳方法.

      If you are communicating with a program that subprocess spawns, you should check out A non-blocking read on a subprocess.PIPE in Python. I had a similar problem with my application and found using queues to be the best way to do ongoing communication with a subprocess.

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

      As for getting values from the user, you can always use the raw_input() builtin to get responses, and for passwords, try using the getpass module to get non-echoing passwords from your user. You can then parse those responses and write them to your subprocess' stdin.

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

      I ended up doing something akin to the following:

      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)
      

      一旦建立了队列并启动了线程,就可以遍历从用户那里获取输入,从进程中获取错误和输出以及处理并将它们显示给用户.

      Once you have the queues made and the threads started, you can loop through getting input from the user, getting errors and output from the process, and processing and displaying them to the user.

      这篇关于从Python内部运行交互式命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 05:21