#2154·click

在点击 launch() 后,默认情况下 WSL2 中会保留 xdg-open 僵尸进程

作者: michjnich创建于 2021年12月16日更新于 2026年8月17日
标签docs

描述

在 WSL2 (我的情况下是 Ubuntu-20.04) 内部调用 click.launch(<url>) 时,会留下一个僵尸进程用于 xdg-open。设置 wait=True 可以避免此问题,这意味着 launch 的文档中:

wait (bool) – 在返回之前等待程序退出。只有在启动的程序阻塞时才有效。特别是,Linux 上的 xdg-open 不会阻塞。 
在 WSL2 中,这些文档可能不完全准确。 
作为一项附加说明,我认为这是一个最近才出现的问题,因为我以前没有注意到此问题,但很难知道它是否与任何特定的包升级或 WSL 实现的变化有关。 
### 复现:
在 WSL2 中的 Python shell 中: 

import click click.launch("https://www.google.com")

网站将在另一个窗口中打开,运行 `ps aux | grep [x]dg-open` 并将看到一个僵尸进程。当然,当父进程 (Python shell) 关闭时,它将消失,但直到那时为止。 
### 预期行为
无论是否传递了 `wait` 标志,都不应有僵尸进程。 
### 建议的解决方案
在 `src/click/_compat.py` 中添加对 WSL 的检查: 

WSL = "microsoft-standard" in package.uname().release 然后在 src/click/_termui_impl.py 中使用此检查,在从 WSL 运行时默认调用 Popen 并使用 wait() (没有将其赋值给变量,我认为这可能会使进程保持打开状态!): if WSL: subprocess.Popen(["xdg-open", url]).wait() else: c = subprocess.Popen(["xdg-open", url]) if wait: return c.wait() 如果出现问题,并且出于任何原因不希望采用此解决方案,那么我认为至少需要修改文档,指出在 WSL 中运行时,应始终设置 wait=True 以避免僵尸进程。

环境:

  • Python 版本: 3.9.9
  • Click 版本: 在 7.1.2 (最初发现此问题) 和 8.0.3 上进行了测试,两者都一样。
  • xdg-open 的当前版本: snapd-xdg-open/focal-updates 2.51.1+20.04ubuntu2 amd64