在进程开始执行后(完成前)向 subprocess.Popen() 提供标准输入

Supply stdin input to subprocess.Popen() after execution of the process had begun ( and before it had finished )

我正在 Python3 中使用远程 shell 实用程序制作一个程序,使用套接字和子进程。到目前为止一切正常,但我遇到了一个我找不到解决方案的问题。这是我的服务器脚本上的代码,它执行从客户端收到的命令:

process = subprocess.Popen(client_buffer.decode('utf-8').split(), stdout = subprocess.PIPE) # Creating a process
        while True: # Reading and sending the stdout from the process in realtime
            shell_output = process.stdout.readline() # Read a line from stdout
            return_code = process.poll()
            print(shell_output)
            print(return_code)
            if shell_output.decode('utf-8') == '' and return_code is not None: 
                #print("Process execution complete. Sending user prefix")
                send(client, ("<#" + color.user + getpass.getuser() + color.endc + "@" + color.dir + cwd() + color.endc + ">").encode('utf-8'))
                break
            elif shell_output: 
                # Process execution incomplete, signaling to client with code 2
                send(client, int_to_bytes(2))
                # And sending the next line of stdout
                send(client, shell_output)

一切正常,我很满意,但有一个限制我不知道如何删除。 也就是说,我可以轻松地为服务器提供带参数的命令,服务器将执行它并将输出发回,效果很好,但是如果命令启动的程序要求额外的输入(例如“(y/n)”问题)在进程执行结束之前(执行中),我不知道如何向进程提供输入。

我可以用 subprocess.Popen() 做这个吗?任何线索都会有所帮助,我提前感谢您。忘记补充了,这个程序是要用在Linux.

P.S definitions/declarations 我没有在代码示例中提供的任何函数和变量都是无关紧要的,但是该项目可以在我的 github 以防有人想看更多代码

通过提供 stdin arg,您可以访问 subprocess'd processes' stdin

p = subprocess.Popen(
    ...
    stdin=subprocess.PIPE,
    ...
)

p.stdin.write("foo")

您也可以只将输入发送到 myprocess.communicate(),但它会阻塞直到完成!

...
stdout, stderr = p.communicate(myinput)

如果您事先知道问题的内容(例如友好 "y\n" * 100),您可以发送大量输入来回答许多问题

首先我觉得readline()这里是有问题的,除非程序的提示以newline()结尾:程序写了一个提示,正在等待答案,而readline()正在等待行尾。我认为您将不得不改用 read() 并做一些更底层的事情。

要真正向程序发送一些东西,我想你可以写信给 process.stdin

看看 pexpect (https://pexpect.readthedocs.io)。我不确定它是否适合您的用例,但如果它适合您的使用情况,它可以让生活更轻松,所以值得努力去找出答案。

另一件需要考虑的事情:许多命令都有一个选项可以使其在没有额外提示的情况下运行,以防止您在 运行 来自另一个程序时遇到的问题。如果您使用的程序是这种情况,那将是迄今为止最简单的解决方案。

好吧,首先是明显而微不足道的错误:

shell_output = process.stdout.readline()

不!您只能写入标准输入并从标准输入读取。

stdout = standard output
stdin = standard input

将管道视为真实管道。 output 流入 其他命令的输入