首页 > 编程问答 >将 python 脚本的 stdin 重定向到 fifo 会导致 RuntimeError: input():lost sys.stdin

将 python 脚本的 stdin 重定向到 fifo 会导致 RuntimeError: input():lost sys.stdin

时间:2024-07-21 01:16:29浏览次数:13  
标签:python bash mingw fifo mkfifo

我有这个 python 脚本,它的作用是充当服务器,它从重定向到 fifo 的 stdin 读取命令:

test.py:

while True:
    try:
        line = input()
    except EOFError:
        break

    print(f'Received: {line}')

在 bash 中运行命令:

mkfifo testfifo
test.py < testfifo &
echo word > testfifo

而不是打印该行收到后,脚本因错误而退出:

Traceback (most recent call last):
  File "test.py", line 5, in <module>
    line = input()
           ^^^^^^^
RuntimeError: input(): lost sys.stdin
[1]+  Exit 1                  test.py < testfifo

我读过一些答案,这些答案说始终需要有一个写入器来打开 fifo。所以我也尝试运行:

sleep 100 > testfifo &

同样的错误。我还尝试用以下内容替换 input() 行:

line = sys.stdin.readline()

而所做的只是给我这个错误:

AttributeError: 'NoneType' object has no attribute 'readline'

我在 Windows 上使用 mingw64,我怀疑这可能是 mingw 的错误。有任何想法吗?谢谢。

编辑:由于这个问题看起来相当无望并且超出了我的控制范围,所以我现在选择只使用 UDP 服务器。 Bash 支持重定向到 /dev/utp/host/port ,这使得这很容易做到。


你观察到的行为是因为当你将 python 脚本的 stdin 重定向到 FIFO,而没有其他进程写入 FIFO 时, sys.stdin 在 Windows 上的 mingw64 中的行为会变得不可预测。这很可能是 mingw64 中的一个错误,或者至少是 Windows 上 FIFO 处理方式的一个怪癖。

尽管在你的原始问题中寻求基于 FIFO 的解决方案似乎没有希望,但让我们探索一些解决方法,以防 FIFO 是绝对要求:

解决方法 1:使用线程化读取器

与其依赖 input() sys.stdin.readline() ,不如创建一个单独的线程来处理来自 FIFO 的读取。这可以防止主线程在等待输入时阻塞,从而可能避免错误。

import threading
import os

def reader_thread(fifo_path):
    with open(fifo_path, 'r') as fifo:
        while True:
            line = fifo.readline()
            if not line:
                break
            print(f'Received: {line.strip()}')

if __name__ == '__main__':
    fifo_path = 'testfifo'
    if not os.path.exists(fifo_path):
        os.mkfifo(fifo_path)

    reader = threading.Thread(target=reader_thread, args=(fifo_path,))
    reader.start()

    reader.join() 

解决方法 2:使用命名管道进行双向通信

与其仅仅依靠 stdin,不如探索使用命名管道来实现 python 脚本和将数据写入其中的进程之间的双向通信。这将允许更强大的交互并可能解决问题。

import os

def server(fifo_in, fifo_out):
    with open(fifo_in, 'r') as fifo_read, open(fifo_out, 'w') as fifo_write:
        while True:
            line = fifo_read.readline()
            if not line:
                break
            message = f'Received: {line.strip()}'
            print(message)
            fifo_write.write(message + '\n')
            fifo_write.flush()

if __name__ == '__main__':
    fifo_in = 'testfifo_in'
    fifo_out = 'testfifo_out'

    if not os.path.exists(fifo_in):
        os.mkfifo(fifo_in)
    if not os.path.exists(fifo_out):
        os.mkfifo(fifo_out)

    server(fifo_in, fifo_out) 

然后,你可以修改你的 bash 脚本以使用这两个 FIFO 进行发送和接收。

请记住,即使使用这些解决方法,mingw64 上与 FIFO 相关的行为也可能不一致。如果你遇到持续存在的问题,你可能需要考虑使用 UDP 套接字(如你所建议的)或探索特定于 Windows 的进程间通信机制(如命名管道)作为更可靠的替代方案。

标签:python,bash,mingw,fifo,mkfifo
From: 78770272

相关文章

  • Python/Flask mysql 游标:为什么它不起作用?
    fromflaskimportFlaskfromflask_mysqldbimportMySQLapp=Flask(__name__)app.config['MYSQL_HOST']='localhost'app.config['MYSQL_USER']='root'app.config['MYSQL_PASSWORD']='password'a......
  • Python pandas to_csv 导致 OSError: [Errno 22] 参数无效
    我的代码如下:importpandasaspdimportnumpyasnpdf=pd.read_csv("path/to/my/infile.csv")df=df.sort_values(['distance','time'])df.to_csv("path/to/my/outfile.csv")此代码成功从infile.csv(一个3GBcsv文件)读取数据,对其进行排......
  • 从 python 中的字符串列表中提取 def 定义函数的标签
    我想使用Python中的正常def过程创建函数,并将标签分配给从字符串列表中提取的命名空间。如何实现这一点?这个问题的动机:我正在创建一个与sympy兼容的python函数库,供数学家用于符号计算实验。许多函数需要初始化具有相关标签的多个对象的系统,这些标签分别由用户提供的字......
  • 在 Raspberry Pi 4 上使用 Python 从具有 SPI 连接的 MT6816 磁性编码器读取
    我对这个领域完全陌生,并不真正知道自己在做什么并且需要帮助。我正在尝试使用MT681614位磁性编码器通过RaspberryPi的SPI连接读取绝对角度。我有以下问题:在硬件方面,是否只是简单地连接必要的连接(3.3V、MOSI、MISO、SCK、GND、CE01)?对于编码......
  • PythonW 不运行脚本。严重地
    因此,使用Windows10和Python3.6。我创建了一个.py脚本,它可以使用命令pythonmyscript.py在命令提示符下正常运行,但是当我制作该脚本的精确副本并为其赋予扩展名.pyw,并尝试使用pythonw运行它时命令pythonwmyscript.pyw,什么也没有发生......
  • 如何使用Python和Selenium模拟产品购买以获取库存信息
    我正在开发一项网络抓取服务,主要针对时尚行业。我的目标是提供有关产品的全面数据,包括库存水平。为了实现这一目标,我需要模拟购买以确定每种尺寸的产品的最大可用数量。我一直在使用Python和Selenium进行网络抓取部分,但在准确模拟购买方面面临着挑战检索股票信息的过程。......
  • 连接Python套接字的问题
    当我写“关闭”时,我试图让我的电报机器人关闭计算机。我不想将机器人连接到网站上的托管。我选择我的手机(AndroidRedmiNote10)作为托管。我在上面安装了Termux和Pydroid。我写了两个文件:main到我的电脑,client到我的手机。通过在计算机上运行这两个文件,一切正常。但是,当我在......
  • 如何修复导入 Numexpr Python 时的错误
    在Windows10Python3.7.9(IDLE)上,我成功安装了“pipinstallnumexpr”,但在“importnumexprasne”时出现错误:Traceback(最近一次调用):文件“<pyshell#21>”,第267行,位于将numexpr导入为ne文件“C:\Python379\lib\site-packages\numexpr_init_.py”......
  • 让 cpython 优化恒定条件
    我正在用Python编写需要尽可能高效运行的代码,但有时我需要深入挖掘调试语句。不要注释这些输入或输出(或者使用外部预处理器来处理代码,就像这里建议的那样Python相当于#ifdefDEBUG或这里如何在python中实现“#ifdef”?|||)我想在模块的开头定义一个变量......
  • 如何使用 for 循环在 python jupyter 笔记本中创建动态图?
    我正在学习本课关于用Python求解热方程。该课程指出,在求解热方程后,我们可以通过在循环中简单地调用pyplot.plot()来可视化解的动画图,其中下面的代码将动态绘制每次每个点的温度,从而得到一个动画情节(课程帖子中提供了动画情节的示例)。importnumpyfrommatplotlibi......