错误“tcgetpgrp失败:不是tty”使用python3打开Web浏览器

mctunoxg  于 2023-01-22  发布在  Python
关注(0)|答案(2)|浏览(187)

下面是我的Windows WSL环境的详细信息:

  • windows 11
  • WSL版本2
  • Ubuntu版本20.04.3 LTS
  • Python 3.8.10语言

我有一个超级简单的Python程序,用来在默认浏览器中打开一个网页。
下面是我的代码:

import webbrowser

webbrowser.open('https://github.com')

当我从终端运行这个命令时,网页按预期打开,但我在终端中也收到这个错误:
tcgetpgrp failed: Not a tty
当我的终端显示这个消息时,光标会向下移动到下一行,看起来像是一个进程挂起了什么的。为了能够使用终端,我必须按Ctrl + C让它给我命令提示符。
我寻找答案,我能找到的一切都与使用Jupyter或PHP有关,但我没有使用它们中的任何一个,我只是使用普通的Python来尝试打开浏览器。
谁能告诉我这里的问题是什么,以及如何解决这个问题/防止它发生?

m1m5dgzv

m1m5dgzv1#

是的,我也可以在WSL下从Ubuntu上的Python(和IPython)REPL中复制它,至少在交互式运行时,我不会遇到需要Ctrl+C的“锁定”。
我会对“为什么”进行理论分析,其中大部分我自己都能证实,但下面的最后一点对我来说仍然是个谜:

  • webbrowser-open首先使用由BROWSER环境变量定义的任何浏览器,但福尔斯到(我相信)xdg-open
  • xdg-open使用alternatives系统中为x-www-browserwww-browser定义的任何浏览器。
  • 在WSL上的Ubuntu 20.04上,默认安装wslu包(不过在22.04下它不再是默认包)。
  • 该软件包包含wslview helper。

[wslview]是WSL上的一个文件查看器,允许您在Windows中从WSL打开文件和文件夹,也是一个假冒的Web浏览器,允许在Windows 10上的默认浏览器中打开URL。

  • wslviewwslu安装期间注册为x-www-browserwww-browser的替代项。
  • webbrowser.open并不只是 callxdg-open,它还尝试获取生成的浏览器的进程信息,以便在请求时(至少)可以打开窗口,其中一部分显然是通过tcgetpgrp系统调用获取进程组。

函数tcgetpgrp()返回fd关联的终端上前台进程组的进程组ID,该终端必须是调用进程的控制终端。

  • 这里我必须稍微“挥手”一下--从webbrowser.openwslview再到binfmt_misc(允许它启动Windows可执行文件的内核系统)的切换中的 * 某个 * 正在“丢失”或重定向终端的文件描述符,从而导致此消息。

在我看来,这似乎是wslview的一个bug(意外的副作用?),因为确保不使用它将防止错误发生。
作为解决方法,可以:

  • export BROWSER=/mnt/c/path/to/windows/browser。注意,我不知道如何指向Edge,因为我知道它没有.exe(它是一个通用/现代/UWP/任何应用程序)。
  • 或者,因为你在Windows 11上,安装一个Linux浏览器。我用Vivaldi测试并确认它在WSL下从Python正确打开。注意,你不能在WSL下sudo apt install Chromium或Firefox,因为它们都是快照。
qmb5sa22

qmb5sa222#

在NotTheDr01ds答案的基础上,可以使用以下命令添加Microsoft Edge:

export BROWSER='/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe'

相关问题