首页 >后端开发 >Python教程 >为什么 Python 的 `subprocess.readlines()` 在流式传输 Ruby 输出时挂起,如何修复它?

为什么 Python 的 `subprocess.readlines()` 在流式传输 Ruby 输出时挂起,如何修复它?

Patricia Arquette
Patricia Arquette原创
2024-12-05 16:32:11816浏览

Why Does Python's `subprocess.readlines()` Hang When Streaming Ruby Output, and How Can I Fix It?

Python Subprocess Readlines() 挂起

问题陈述:

尝试流式传输时使用 subprocess 模块在 Python 中逐行读取 Ruby 文件,readlines() 调用块无限期地阻止进一步执行。

原因:

在非 Linux 操作系统上使用 pty 模块模拟伪终端时,可能会出现此问题。 pty 是 Linux 特定的库,不保证其在其他系统上的行为。

解决方案:

1.使用 Pexpect:

Pexpect 是一个跨平台库,专为自动化交互式应用程序而设计。它提供了一个用于通过伪终端发送和接收数据的高级接口。

import pexpect

pexpect.run("ruby ruby_sleep.rb", logfile=sys.stdout)

2.使用 Stdbuf:

Stdbuf 可用于在非交互模式下启用行缓冲,允许在每一行上刷新输出。

proc = Popen(['stdbuf', '-oL', 'ruby', 'ruby_sleep.rb'],
             bufsize=1, stdout=PIPE, stderr=STDOUT, close_fds=True)
for line in iter(proc.stdout.readline, b''):
    print(line)
proc.stdout.close()
proc.wait()

3.使用标准库中的 Pty(适用于 Linux):

import errno
import os
import pty
from subprocess import Popen, STDOUT

master_fd, slave_fd = pty.openpty()  # provide tty to enable line-buffering on Ruby's side
proc = Popen(['ruby', 'ruby_sleep.rb'],
             stdin=slave_fd, stdout=slave_fd, stderr=STDOUT, close_fds=True)
os.close(slave_fd)
try:
    while 1:
        try:
            data = os.read(master_fd, 512)
        except OSError as e:
            if e.errno != errno.EIO:
                raise
            break  # EIO means EOF on some systems
        else:
            if not data:  # EOF
                break
            print('got ' + repr(data))
finally:
    os.close(master_fd)
    if proc.poll() is None:
        proc.kill()
    proc.wait()
print("This is reached!")

以上是为什么 Python 的 `subprocess.readlines()` 在流式传输 Ruby 输出时挂起,如何修复它?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn