Python 子进程 readlines() 挂起

2023-11-26

我尝试完成的任务是流式传输 ruby​​ 文件并打印输出。 (NOTE:我不想一次打印出所有内容)

main.py

from subprocess import Popen, PIPE, STDOUT

import pty
import os

file_path = '/Users/luciano/Desktop/ruby_sleep.rb'

command = ' '.join(["ruby", file_path])

master, slave = pty.openpty()
proc = Popen(command, bufsize=0, shell=True, stdout=slave, stderr=slave, close_fds=True)     
stdout = os.fdopen(master, 'r', 0)

while proc.poll() is None:
    data = stdout.readline()
    if data != "":
        print(data)
    else:
        break

print("This is never reached!")

ruby_sleep.rb

puts "hello"

sleep 2

puts "goodbye!"

Problem


我假设你使用pty由于中概述的原因问:为什么不直接使用管道(popen())?(到目前为止所有其他答案都忽略你的“注意:我不想一次打印出所有内容”).

pty仅限 Linux正如文档中所说:

由于伪终端处理高度依赖于平台,因此 是仅适用于 Linux 的代码。 (Linux 代码应该可以工作 其他平台也可以使用,但尚未测试。)

目前尚不清楚它在其他操作系统上的运行情况如何。

你可以尝试pexpect:

import sys
import pexpect

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

Or stdbuf在非交互模式下启用行缓冲:

from subprocess import Popen, PIPE, STDOUT

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()

或者使用pty来自 stdlib 基于@Antti Haapala 的回答:

#!/usr/bin/env python
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!")

所有三个代码示例都会立即打印“hello”(一旦看到第一个 EOL)。


leave the old more complicated code example here because it may be referenced and discussed in other posts on SO

或者使用pty基于@Antti Haapala 的回答:

import os
import pty
import select
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'],
             stdout=slave_fd, stderr=STDOUT, close_fds=True)
timeout = .04 # seconds
while 1:
    ready, _, _ = select.select([master_fd], [], [], timeout)
    if ready:
        data = os.read(master_fd, 512)
        if not data:
            break
        print("got " + repr(data))
    elif proc.poll() is not None: # select timeout
        assert not select.select([master_fd], [], [], 0)[0] # detect race condition
        break # proc exited
os.close(slave_fd) # can't do it sooner: it leads to errno.EIO error
os.close(master_fd)
proc.wait()

print("This is reached!")
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 子进程 readlines() 挂起 的相关文章

随机推荐

  • 为什么我无法使用 JQuery .html 添加

    为什么这段代码有效 div error container html div class error No more foo allowed div 但这段代码会导致错误 div error container html div class
  • Log4j2:SMTPAppender 不发送错误或致命级别的邮件

    我发现 log4j2 中的 SMTPAppender 有一些问题 每当记录具有以下级别的事件时error or fatal被创建without举办具有级别的活动info在没有邮件发送并且致命事件消失之前 这是我的 log4j2 配置文件 l
  • 如何将这些 SQL SELECT 查询合并到一个 SELECT 语句中

    如何将这两个 select 语句合并到一个查询中 SELECT SUM incidents AS fires neighborhoods AS fire neighborhoods FROM SELECT FROM fires 2009 i
  • `RefCell` 无法在线程之间安全共享?

    这是一个延续如何在 Rust 的闭包内重用外部作用域的值 为了更好的呈现 开通了新的Q main rs The value will be modified eventually inside main and a http request
  • CSS 响应式左浮动和右浮动(更改哪个 div 位于顶部)?

    我正在这个页面上工作 http www insidemarketblog com test 4 您会看到单词 test 位于左侧浮动的 div 中 图像位于右侧浮动的 div 中 如果调整它的大小 您会看到左浮动的 div 位于顶部 右浮动
  • 打开一个新的弹出窗口并向其发布数据

    我正在使用 jQuery 打开一个弹出窗口 我想在它打开时使用 post 方法向其发送数据 任何人都可以帮助我 提前致谢 我目前正在使用 get 方法传递数据 因此数据是 url 中的一部分 但我不希望数据在 url 中可见 functio
  • 在哪里可以找到 TensorFlow 2.0 的tensorflow.contrib.layers

    我一直在 TensorFlow 中开发机器学习代码contrib layers 我对这个模块很满意 它工作得很好 让我能够充分控制我的模型 然而 TensorFlow 2 0将完全删除contrib模块和新的keras模块在没有额外努力的情
  • 以编程方式获取页面的屏幕截图

    我正在编写一个供内部使用的专用爬虫和解析器 并且我需要能够截取网页的屏幕截图 以便检查整个过程中使用的颜色 该程序将接收大约十个网址并将它们保存为位图图像 从那里我计划使用 LockBits 来创建图像中最常用的五种颜色的列表 据我所知 这
  • 使用分页查看目录中的文件 - php

    我想在浏览器中显示我的目录中的文件 我知道这可以使用 opendir and readdir 但我想要的是将列表中的文件数量限制为特定数量并使用分页显示下一个 你可以使用scandir将目录的所有内容读入数组 然后根据分页值输出数组的内容
  • isInstance 和 isInstanceOf 之间的区别

    之间有区别吗classOf String isInstance 42 and 42 isInstanceOf String 如果是 你能解释一下吗 对于引用类型 那些扩展AnyRef 最终结果没有区别 isInstanceOf然而 我们非常
  • KafkaStreams:获取窗口最终结果

    是否可以得到窗口最终结果在 Kafka Streams 中通过抑制中间结果 我无法实现这个目标 我的代码有什么问题吗 val builder StreamsBuilder builder stream
  • 导入 CSV 文件时如何删除文本周围的双引号?

    我有类似于以下内容的数据 D STEIN DS 01 ALTRES TTTTTTFFTT D STEIN DS 01 APCASH TTTTTTFFTT D STEIN DS 01 APINH TTTTTTFFTT D STEIN DS 0
  • 使用 java nio 路径时未安装 JBoss wildfly 8.x 提供程序“vfs”

    我正在尝试将 spring 应用程序从 glassfish 4 导出到 JBoss wildfly 8 x 或 9 alpha 但是当我的应用程序在代码的某些部分启动时会引发异常 Caused by java lang RuntimeExc
  • e.srcElement 在 Firefox 中未定义?

    我正在开发一个网站 现在正在所有浏览器中进行测试 我目前正在 firefox 中进行测试 并且在使用 event sourceElement 时发现错误 我需要 e srcElement 做的是返回值 下面我展示了一个关于如何获取返回的值
  • 关于太多开放数字的警告

    在我创建许多人物的脚本中fix ax plt subplots 我收到警告运行时警告 已打开超过 20 个数字 通过 pyplot 接口创建的图形 matplotlib pyplot figure 会保留到显式关闭为止 并且可能会消耗太多内
  • 在 Web api 控制器中手动验证模型

    我有一个名为 用户 的类和一个属性 名称 public class User Required public string Name get set api控制器方法是 public IHttpActionResult PostUser U
  • @PathVariable 和 @ModelAttribute 的值重叠

    我有一个User存储在会话中的对象 SessionAttributes 以及一个直接的方法装饰 ModelAttribute以便在会话值为空时初始化它 用户类别 Entity Table name USER public class Use
  • 实现包含其他 Parcelable 的 Parcelable 时出现问题

    我正在实现 Parcelable 类 其中有另一个 Parcelable 在 OuterParcelable 类中 Override public void writeToParcel Parcel dest int flags Bundl
  • UnicodeDecodeError,utf-8 无效的连续字节

    我正在尝试使用该代码从日志文件中提取行 with open fichier 01 as f content f readlines print content 但它总是发出错误声明 Traceback most recent call la
  • Python 子进程 readlines() 挂起

    我尝试完成的任务是流式传输 ruby 文件并打印输出 NOTE 我不想一次打印出所有内容 main py from subprocess import Popen PIPE STDOUT import pty import os file