在Windows上具有常量输出的Python无块子进程输入

前端之家收集整理的这篇文章主要介绍了在Windows上具有常量输出的Python无块子进程输入前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用subproccess和_thread模块运行命令.子进程有一个输出流.为了解决这个问题,我使用了两个线程,一个不断打印新线,另一个是检查输入.当我通过proc.stdin.write(‘Some string’)传递子进程输入时,它返回1然后我没有输出.沟通不能像我读过的大多数其他问题一样工作,因为它会阻止等待EOF,尽管它确实打印了将要返回的任何内容的第一行.我看到了一些使用’pty’的解决方案,但Windows不支持它.

如果您想自己尝试,服务器文件夹中的文件只是一个Minecraft服务器.

from subprocess import Popen,PIPE
import _thread
import sys
# asdf
proc = None
run = True
stdout = None
stdin = None


def getInput():
    global proc
    global run,stdin,stdout
    print("Proc inside the get input funct"+str(proc))
    inputs = input("Enter Something" + "\n")
    print("YOU ENTERED:",inputs)
    print("ATTEMPTING TO PIPE IT INTO THE CMD")
    run = True

    """----------------------------------------"""
    """        Works but blocks outputs        """
    """----------------------------------------"""
    # out,err=proc.communicate(bytes(inputs,'UTF-8'))
    # proc.stdin.flush()
    # print("Out is: "+out)




    """----------------------------------------"""
    """   Doesn't write but doesn't block      """
    """----------------------------------------"""
    # test = 0
    # test=proc.stdin.write(bytes(inputs,'UTF-8'))
    # print(test)
    # proc.stdin.flush()


def execute(command):
    global proc,stdout
    proc = Popen(command,cwd='C://Users//Derek//Desktop//server//',stdin=PIPE,stdout=PIPE,stderr=stdout,shell=True)
    lines_iterator = iter(proc.stdout.readline,"")
    print("Proc inside of the execute funct:"+str(proc))
    # print(lines_iterator)
    for line in lines_iterator:
        # print(str(line[2:-1]))
        # if line.decode('UTF-8') != '':
        print(line[:-2].decode('UTF-8')),# yield line
        sys.stdout.flush()


threadTwo = _thread.start_new_thread(execute,(["java","-jar","minecraft_server.jar"],))

while 1:
    if run and proc!=None:
        run = False
        threadOne = _thread.start_new_thread(getInput,( ))

    pass
proc.communicate()等待子进程完成,因此它最多可以使用一次 – 你可以一次传递所有输入并在子进程退出后获得所有输出.

如果您不修改输入/输出,则不需要重定向子进程’stdin / stdout.

要将输入提供给后台线程中的子进程,并在它逐行到达时立即打印输出

#!/usr/bin/env python3
import errno
from io import TextIOWrapper
from subprocess import Popen,PIPE
from threading import Thread

def Feed(pipe):
    while True:
        try: # get input
            line = input('Enter input for minecraft')
        except EOFError:
            break # no more input
        else:
            # ... do something with `line` here

            # Feed input to pipe
            try:
                print(line,file=pipe)
            except BrokenPipeError:
                break # can't write to pipe anymore
            except OSError as e:
                if e.errno == errno.EINVAL:
                    break  # same as EPIPE on Windows
                else:
                    raise # allow the error to propagate

    try:
        pipe.close() # inform subprocess -- no more input
    except OSError:
        pass # ignore

with Popen(["java",cwd=r'C:\Users\Derek\Desktop\server',bufsize=1) as p,\
     TextIOWrapper(p.stdin,encoding='utf-8',write_through=True,line_buffering=True) as text_input:
    Thread(target=Feed,args=[text_input],daemon=True).start()
    for line in TextIOWrapper(p.stdout,encoding='utf-8'):
        # ... do something with `line` here
        print(line,end='')

关于p.stdin的注意事项:

> print()在每行的末尾添加换行符.这是必要的,因为input()剥离换行符
>每行后调用p.stdin.flush()(line_buffering = True)

Minecraft的输出可能会被延迟,直到其stdout缓冲区被刷新.

如果你没有什么可以添加“在这里做一些事情”评论,那么不要重定向相应的管道(暂时忽略字符编码问题).

TextIOWrapper默认使用通用换行模式.如果您不想要,请明确指定换行参数.

猜你在找的Windows相关文章