简体   繁体   English

Subprocess.Popen Stdout 等待程序完成

[英]Subprocess.Popen Stdout Waiting for Program Finish

I'm running a program via subprocess.Popen and running into an unexpected issue wherein the stdout does not print live, and instead waits for the program to finish.我正在通过subprocess.Popen运行一个程序并遇到一个意想不到的问题,其中stdout没有实时打印,而是等待程序完成。 Oddly enough, this only occurs when the program being called is written in Python.奇怪的是,这只发生在被调用的程序是用 Python 编写的。

My control program (the one using subprocess) is as follows:我的控制程序(使用子进程的那个)如下:

import subprocess
import os
print("Warming up")
pop = subprocess.Popen("python3 signaler.py", shell=True,stdout=subprocess.PIPE,stdin=subprocess.PIPE)
for line in pop.stdout:
    print(line)
print("I'm done")

Signaler.py:信号器.py:

import time
print("Running")
time.sleep(5)
print("Done running")

When I run the control program, output is as follows.当我运行控制程序时,输出如下。 The code waits 5 seconds before printing Running , despite the fact that print("Running") occurs before the actual delay.尽管print("Running")发生在实际延迟之前,但代码在打印Running之前会等待 5 秒。

Warming up
*waits 5 seconds*
b'Running\n'
b'123\n'
I'm done

The strange thing is that when I modify the control program to instead run a Node program, the delay functions as expected and Running is printed 5 seconds before Done Running .奇怪的是,当我修改控制程序以运行 Node 程序时,延迟功能按预期Running ,并且RunningDone Running之前打印 5 秒。 The Node program is as follows: Node程序如下:

const delay = require("delay")
async function run(){
console.log("Running")
await delay(5000)
console.log("Done running")
}
run()

This issue doesn't occur when I use os.system to call signaler.py, and still occurs when I run shell=False and modify the arguments as such.当我使用os.system调用os.system时不会发生此问题,并且在我运行shell=False并像这样修改参数时仍然会发生此问题。 Any ideas what's causing this?任何想法是什么原因造成的?

It sounds like python is buffering the output of the print function and javascript isn't.听起来 python 正在缓冲print函数的输出,而 javascript 不是。 You can force print statements to be flushed to stdout by calling it with the flush keyword in signaler.py您可以通过在signaler.py使用 flush 关键字调用它来强制将打印语句刷新到标准输出

print("Running", flush=True)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM