子进程 Popen 的标准输出为空,如果子进程是一个 Python 脚本。

huangapple go评论73阅读模式
英文:

Subprocess Popen stdout is empty if the subprocess is a Python script

问题

以下是翻译好的部分:

这里有一些代码,应该在终端中打印出数字0到4:(修改自https://stackoverflow.com/a/59291466/4391249)

import os
import time
import subprocess

cmd = 'python', '-c', 'import time; [(print(i), time.sleep(1)) for i in range(5)]'
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
os.set_blocking(p.stdout.fileno(), False)
start = time.time()
while True:
    # 在非阻塞模式下,第一次迭代始终产生空的字节字符串
    line = p.stdout.readline()
    if len(line):
        print(line)
    if time.time() > start + 5:
        break
p.terminate()

但是对我来说并不起作用。对我来说,什么都没有被打印出来。

当我将cmd = 'ls'时,它会产生预期的输出(打印我的工作目录的内容)。

为什么Python版本不起作用?

我使用的是Ubuntu20.04和Python3.10。

英文:

Here is some code that should print numbers 0 through 4 to the terminal: (adapted from https://stackoverflow.com/a/59291466/4391249)

import os
import time
import subprocess

cmd = 'python', '-c', 'import time; [(print(i), time.sleep(1)) for i in range(5)]'
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
os.set_blocking(p.stdout.fileno(), False)
start = time.time()
while True:
    # first iteration always produces empty byte string in non-blocking mode
    line = p.stdout.readline()
    if len(line):
        print(line)
    if time.time() > start + 5:
        break
p.terminate()

But it doesn't for me. For me, nothing is printed.

When I instead set cmd = 'ls', it does produce the expected output (prints the contents of my working directory).

Why doesn't the Python one work?

I'm on Ubuntu20.04 with Python3.10.

答案1

得分: 1

禁用输出缓冲使用 -u 命令行标志:

import os
import time
import subprocess

cmd = [
    '/Users/xyz/.pyenv/shims/python', '-u', '-c',
    'import time; [(print(i), time.sleep(1)) for i in range(5)]';
]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
os.set_blocking(p.stdout.fileno(), False)
start = time.time()
while True:
    # 第一次迭代总是以非阻塞模式生成空的字节字符串
    line = p.stdout.readline()
    if len(line):
        print(line)
    if time.time() > start + 5:
        break
    p.terminate()

输出:

b'0\n'
b'1\n'
b'2\n'
b'3'
b'\n'
b'4\n'
英文:

Disable output buffering using -u cli flag:

import os
import time
import subprocess

cmd = [
    '/Users/xyz/.pyenv/shims/python', '-u', '-c',
    'import time; [(print(i), time.sleep(1)) for i in range(5)]'
]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
os.set_blocking(p.stdout.fileno(), False)
start = time.time()
while True:
    # first iteration always produces empty byte string in non-blocking mode
    line = p.stdout.readline()
    if len(line):
        print(line)
    if time.time() > start + 5:
        break
p.terminate()

Out:

b'0\n'
b'1\n'
b'2\n'
b'3'
b'\n'
b'4\n'

huangapple
  • 本文由 发表于 2023年2月23日 23:02:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75546587.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定