Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

OSError: [Errno 6] No such device or address: '/proc/self/fd/1' when using asyncio.create_subprocess_*

未關閉
#505 1 則留言 2 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

評估

難度
4/5
預估耗時
3-5 天
新手友好度
38/100
Issue 類型
缺陷
描述清晰度
基本清楚
活躍度
停滯
技術堆疊
python
領域
networking

研究方向

首先使用原生 asyncio 和 uvloop 執行提供的 proof of concept,重點關注 asyncio.create_subprocess_shell、PIPE 處理以及 uvloop.EventLoopPolicy。比較 stdout 和 stderr 檔案描述元以及錯誤輸出;當理解了回報的子程序管線行為,且重現不再產生 OSError 時,即表示完成。

由索引模型根據 Issue 內容生成。

描述

  • uvloop==0.16.0 and uvloop==0.17.0:
  • python3.8.10 and python3.10.5:
  • Platform: Ubuntu20.04:
  • Can you reproduce the bug with PYTHONASYNCIODEBUG in env? -> Yes, but there is not more output:
  • Does uvloop behave differently from vanilla asyncio? How? It uses socket instead of pipe for the file descriptors of the subprocess. This gives me an OSError6:

Uvloop does not handle subprocess pipes properly. It doesn not matter if I use asyncio.subprocess.PIPE or subprocess.PIPE. How can I access stdout/stderr of a asyncio subprocess? Is this behavior intended?

Running the proof of concept:

import asyncio, subprocess
async def poc():
    proc = await asyncio.create_subprocess_shell(
        "ls -lsh /proc/self/fd",
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE,
    )
    stdout, stderr = await proc.communicate()
    print(stdout, stderr)
    proc = await asyncio.create_subprocess_shell(
        "python3 -c \"f=open('/proc/self/fd/1', 'w'); f.write('test')\"", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
    )
    stdout, stderr = await proc.communicate()
    print(stdout, stderr)

async def poc1():
    proc = await asyncio.create_subprocess_shell(
        "ls -lsh /proc/self/fd",
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE,
    )
    stdout, stderr = await proc.communicate()
    print(stdout, stderr)
    proc = await asyncio.create_subprocess_shell(
        "python3 -c \"f=open('/proc/self/fd/1', 'w'); f.write('test')\"", stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )
    stdout, stderr = await proc.communicate()
    print(stdout, stderr)

print("Default loop")
asyncio.run(poc())
asyncio.run(poc1())

import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

print("uvloop")
print("asyncio pipe")
asyncio.run(poc())
print("subprocess pipe")
asyncio.run(poc1())

Yields the following output:

Default loop
b'total 0\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 0 -> /dev/pts/10\n0 l-wx------ 1 peter peter 64 Sep 22 12:19 1 -> pipe:[8435934]\n0 l-wx------ 1 peter peter 64 Sep 22 12:19 2 -> pipe:[8435935]\n0 lr-x------ 1 peter peter 64 Sep 22 12:19 3 -> /proc/625365/fd\n' b''
b'test' b''
b'total 0\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 0 -> /dev/pts/10\n0 l-wx------ 1 peter peter 64 Sep 22 12:19 1 -> pipe:[8435942]\n0 l-wx------ 1 peter peter 64 Sep 22 12:19 2 -> pipe:[8435943]\n0 lr-x------ 1 peter peter 64 Sep 22 12:19 3 -> /proc/625371/fd\n' b''
b'test' b''
uvloop
asyncio pipe
b'total 0\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 0 -> /dev/pts/10\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 1 -> socket:[8435953]\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 2 -> socket:[8435955]\n0 lr-x------ 1 peter peter 64 Sep 22 12:19 3 -> /proc/625376/fd\n' b''
b'' b'Traceback (most recent call last):\n  File "<string>", line 1, in <module>\nOSError: [Errno 6] No such device or address: \'/proc/self/fd/1\'\n'
subprocess pipe
b'total 0\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 0 -> /dev/pts/10\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 1 -> socket:[8396454]\n0 lrwx------ 1 peter peter 64 Sep 22 12:19 2 -> socket:[8396456]\n0 lr-x------ 1 peter peter 64 Sep 22 12:19 3 -> /proc/625380/fd\n' b''
b'' b'Traceback (most recent call last):\n  File "<string>", line 1, in <module>\nOSError: [Errno 6] No such device or address: \'/proc/self/fd/1\'\n'

As we can see, once uvloop is running the calls that worked earlier are crashing. The observable difference is that uvloop maps sockets to stdout/stderr whereas default asyncio uses pipes

主要語言
Cython
星號
11.9k
分支
615
PR 合併指標
30 天內沒有已合併 PR

環境準備

我們還沒有檢查這個專案的環境設定檔。先看它的 README,通用步驟見我們的新手貢獻指南。

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

MagicStack/uvloop 的其他 Issue

查看 MagicStack/uvloop 的全部 Issue

相似的 Issue

更多 Networking Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。