1. <legend id='fQPHm'><style id='fQPHm'><dir id='fQPHm'><q id='fQPHm'></q></dir></style></legend>

    1. <tfoot id='fQPHm'></tfoot>
      <i id='fQPHm'><tr id='fQPHm'><dt id='fQPHm'><q id='fQPHm'><span id='fQPHm'><b id='fQPHm'><form id='fQPHm'><ins id='fQPHm'></ins><ul id='fQPHm'></ul><sub id='fQPHm'></sub></form><legend id='fQPHm'></legend><bdo id='fQPHm'><pre id='fQPHm'><center id='fQPHm'></center></pre></bdo></b><th id='fQPHm'></th></span></q></dt></tr></i><div id='fQPHm'><tfoot id='fQPHm'></tfoot><dl id='fQPHm'><fieldset id='fQPHm'></fieldset></dl></div>
        <bdo id='fQPHm'></bdo><ul id='fQPHm'></ul>
    2. <small id='fQPHm'></small><noframes id='fQPHm'>

      使用 Python 进行交互式输入/输出

      时间:2023-07-22
      <legend id='E7IqY'><style id='E7IqY'><dir id='E7IqY'><q id='E7IqY'></q></dir></style></legend>

      <small id='E7IqY'></small><noframes id='E7IqY'>

      <i id='E7IqY'><tr id='E7IqY'><dt id='E7IqY'><q id='E7IqY'><span id='E7IqY'><b id='E7IqY'><form id='E7IqY'><ins id='E7IqY'></ins><ul id='E7IqY'></ul><sub id='E7IqY'></sub></form><legend id='E7IqY'></legend><bdo id='E7IqY'><pre id='E7IqY'><center id='E7IqY'></center></pre></bdo></b><th id='E7IqY'></th></span></q></dt></tr></i><div id='E7IqY'><tfoot id='E7IqY'></tfoot><dl id='E7IqY'><fieldset id='E7IqY'></fieldset></dl></div>
          <tbody id='E7IqY'></tbody>

            <bdo id='E7IqY'></bdo><ul id='E7IqY'></ul>

              <tfoot id='E7IqY'></tfoot>

              • 本文介绍了使用 Python 进行交互式输入/输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                我有一个与用户交互的程序(就像一个 shell),我想使用 Python 子进程模块交互地运行它.这意味着,我希望能够写入标准输入并立即从标准输出中获取输出.我尝试了这里提供的许多解决方案,但似乎没有一个能满足我的需求.

                I have a program that interacts with the user (acts like a shell), and I want to run it using the Python subprocess module interactively. That means, I want the possibility to write to standard input and immediately get the output from standard output. I tried many solutions offered here, but none of them seems to work for my needs.

                我编写的代码基于 运行交互式Python 中的命令.

                The code I've written is based on Running an interactive command from within Python.

                import Queue
                import threading
                import subprocess
                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 Queue.Empty:
                        return outStr
                
                p = subprocess.Popen("./a.out", stdin=subprocess.PIPE, stout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize = 1)
                #p = subprocess.Popen("./a.out", stdin=subprocess.PIPE, stout=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()
                
                p.stdin.write("1
                ")
                p.stdin.flush()
                errors = getOutput(errQueue)
                output = getOutput(outQueue)
                
                p.stdin.write("5
                ")
                p.stdin.flush()
                erros = getOutput(errQueue)
                output = getOutput(outQueue)
                

                问题是队列仍然是空的,好像没有输出一样.只有当我将程序需要执行和终止的所有输入写入标准输入时,我才会得到输出(这不是我想要的).例如,如果我这样做:

                The problem is that the queue remains empty, as if there is no output. Only if I write to standard input all the input that the program needs to execute and terminate, then I get the output (which is not what I want). For example, if I do something like:

                p.stdin.write("1
                5
                ")
                errors = getOutput(errQueue)
                output = getOutput(outQueue)
                

                有没有办法做我想做的事?

                Is there a way to do what I want to do?

                脚本将在 Linux 机器上运行.我更改了脚本并删除了 universal_newlines=True + 将 bufsize 设置为 1 并在写入后立即刷新标准输入.我仍然没有得到任何输出.

                The script will run on a Linux machine. I changed my script and deleted the universal_newlines=True + set the bufsize to 1 and flushed standard input immediately after write. Still I don't get any output.

                第二次尝试:

                我尝试了这个解决方案,它对我有用:

                I tried this solution and it works for me:

                from subprocess import Popen, PIPE
                
                fw = open("tmpout", "wb")
                fr = open("tmpout", "r")
                p = Popen("./a.out", stdin = PIPE, stdout = fw, stderr = fw, bufsize = 1)
                p.stdin.write("1
                ")
                out = fr.read()
                p.stdin.write("5
                ")
                out = fr.read()
                fw.close()
                fr.close()
                

                推荐答案

                Linux 上这个问题的两种解决方案:

                Two solutions for this issue on Linux:

                第一个是使用文件将输出写入并同时读取:

                First one is to use a file to write the output to, and read from it simultaneously:

                from subprocess import Popen, PIPE
                
                fw = open("tmpout", "wb")
                fr = open("tmpout", "r")
                p = Popen("./a.out", stdin = PIPE, stdout = fw, stderr = fw, bufsize = 1)
                p.stdin.write("1
                ")
                out = fr.read()
                p.stdin.write("5
                ")
                out = fr.read()
                fw.close()
                fr.close()
                

                第二,正如 J.F. Sebastian 提供的,是使用 fnctl 模块使 p.stdout 和 p.stderr 管道非阻塞:

                Second, as J.F. Sebastian offered, is to make p.stdout and p.stderr pipes non-blocking using fnctl module:

                import os
                import fcntl
                from subprocess import Popen, PIPE  
                def setNonBlocking(fd):
                    """
                    Set the file description of the given file descriptor to non-blocking.
                    """
                    flags = fcntl.fcntl(fd, fcntl.F_GETFL)
                    flags = flags | os.O_NONBLOCK
                    fcntl.fcntl(fd, fcntl.F_SETFL, flags)
                
                p = Popen("./a.out", stdin = PIPE, stdout = PIPE, stderr = PIPE, bufsize = 1)
                setNonBlocking(p.stdout)
                setNonBlocking(p.stderr)
                
                p.stdin.write("1
                ")
                while True:
                    try:
                        out1 = p.stdout.read()
                    except IOError:
                        continue
                    else:
                        break
                out1 = p.stdout.read()
                p.stdin.write("5
                ")
                while True:
                    try:
                        out2 = p.stdout.read()
                    except IOError:
                        continue
                    else:
                        break
                

                这篇关于使用 Python 进行交互式输入/输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                上一篇:使用 Python 子进程通信方法时如何获取退出代码? 下一篇:Python subprocess.call 一个 bash 别名

                相关文章

                    <bdo id='Rb0Fk'></bdo><ul id='Rb0Fk'></ul>

                1. <tfoot id='Rb0Fk'></tfoot><legend id='Rb0Fk'><style id='Rb0Fk'><dir id='Rb0Fk'><q id='Rb0Fk'></q></dir></style></legend>

                  <small id='Rb0Fk'></small><noframes id='Rb0Fk'>

                    <i id='Rb0Fk'><tr id='Rb0Fk'><dt id='Rb0Fk'><q id='Rb0Fk'><span id='Rb0Fk'><b id='Rb0Fk'><form id='Rb0Fk'><ins id='Rb0Fk'></ins><ul id='Rb0Fk'></ul><sub id='Rb0Fk'></sub></form><legend id='Rb0Fk'></legend><bdo id='Rb0Fk'><pre id='Rb0Fk'><center id='Rb0Fk'></center></pre></bdo></b><th id='Rb0Fk'></th></span></q></dt></tr></i><div id='Rb0Fk'><tfoot id='Rb0Fk'></tfoot><dl id='Rb0Fk'><fieldset id='Rb0Fk'></fieldset></dl></div>