ubuntu桌面版chatgpt work一直reconnecting:代理环境变量排障复盘

系统:Ubuntu 26.04
设备:Lenovo Y7000
客户端:ChatGPT Linux 桌面版
网络代理:*** Verge,本地端口 127.0.0.1:7897

一、故障现象

ChatGPT 桌面版的普通对话可以正常使用,但 Work 模式持续出现:

text 复制代码
Reconnecting 1/5

...

Reconnecting 5/5

waiting for network

典型现象包括:

  • 普通 ChatGPT 对话可以收发消息;

  • 浏览器和其他联网应用工作正常;

  • Work 运行一段时间后不断重连;

  • 重启 ChatGPT 后仍然复现;

  • 同一台电脑上的网页版 Work 等待约半分钟后可以正常回复;

  • Linux 桌面版 Work 仍停留在 Reconnecting

最终通过A/B测试确认:

从 GNOME 应用图标启动 ChatGPT 时,主进程没有获得终端中已有的 *** 代理环境变量;它启动的 Codex app-server 同样没有继承代理变量,因此 Work 的部分网络请求超时。把代理变量加入用户级 .desktop 启动命令后,从桌面图标启动的 Work 恢复正常。

二、最关键的 A/B 测试:网页版与桌面版对照

在同一台电脑、同一个账号、同一网络环境中测试:

text 复制代码
网页版 Work:约半分钟后正常回复

桌面版 Work:持续 Reconnecting

这个对照一次排除了很多方向:

  • 不是当前网络完全无法访问互联网;

  • 不是 Work 服务对该账号完全不可用;

  • 不是 OpenAI 所有访问路径都失败。

问题范围被缩小到:

text 复制代码
Linux 桌面客户端

或

桌面客户端启动的本地 Work/Codex 后端

或

桌面客户端特有的代理与网络环境

这比不断重启 ChatGPT、重装应用或反复修改系统网络设置更有效。

三、确认桌面客户端及其本地后端确实已启动

先查看 ChatGPT 相关进程:

bash 复制代码
ps aux | grep -i chatgpt

命令含义:

  • ps:列出进程;

  • a:显示更多用户和终端相关进程;

  • u:用详细的用户格式显示;

  • x:包括没有绑定终端的进程;

  • |:把左侧输出交给右侧;

  • grep -i chatgpt:只保留包含 chatgpt 的行,并忽略大小写。

输出表明主程序是:

text 复制代码
/usr/lib/chatgpt/ChatGPT

同时可以看到 ChatGPT 启动了本地 Codex 后端:

text 复制代码
/usr/lib/chatgpt/resources/codex ... app-server

这说明问题不是"Work 后端根本没有启动"。下一步应检查:后端虽然启动了,为什么网络请求仍失败。

四、从日志中确认超时发生在 Work 请求链路

当时用下面的命令读取最近 5 分钟的用户级 systemd 日志,并筛选与 ChatGPT、Codex、网络和错误有关的行:

bash 复制代码
journalctl --user --since "5 minutes ago" | grep -Ei 'chatgpt|codex|websocket|network|error|failed'

命令可以拆开理解:

  • journalctl:读取 systemd journal 日志;

  • --user:只查看当前用户会话中的服务和桌面程序日志,而不是整个系统的内核与系统服务日志;

  • --since "5 minutes ago":只读取最近 5 分钟,避免旧日志干扰;

  • |:把左侧日志交给右侧继续处理;

  • grep -E:使用扩展正则表达式,允许在引号内用 | 表示"或者";

  • grep -i:忽略大小写;

  • 引号中的关键词:只保留可能与 ChatGPT、Codex、连接或错误有关的行。

筛选结果中出现过一条类似记录。原日志是一整行,这里为了便于阅读拆成三个字段:

text 复制代码
method=app/read

durationMs=30223

errorCode=-32603

以及:

text 复制代码
failed to read app metadata

Failed to send request

以及同一时刻 Work 界面持续 Reconnecting,可以合理推断失败发生在 Work 加载应用元数据的请求链路,并具有典型的请求超时特征。

五、检查进程是否继承代理环境变量

终端中已经存在 *** 代理变量:

text 复制代码
HTTP_PROXY=http://127.0.0.1:7897

HTTPS_PROXY=http://127.0.0.1:7897

ALL_PROXY=socks://127.0.0.1:7897

但终端里有代理,不代表从 GNOME 图标启动的程序也有代理。

1. 检查终端环境

bash 复制代码
env | grep -i proxy
  • env:显示当前进程的环境变量;

  • grep -i proxy:只看名称包含 proxy 的变量,忽略大小写。

终端能够正常显示 HTTP_PROXYHTTPS_PROXYALL_PROXY 等变量。

2. 检查 ChatGPT 或 Codex 后端进程环境

先找到目标进程 PID,再读取:

bash 复制代码
tr '\0' '\n' < /proc/进程PID/environ | grep -i proxy

其中:

  • /proc/PID/environ:Linux 暴露的该进程环境变量;

  • 环境变量之间使用 NUL 字符分隔,不是普通换行;

  • tr '\0' '\n':把 NUL 分隔符转换成可读的换行;

  • grep -i proxy:筛选代理变量。

检查结果没有任何输出。

当时的差异非常清楚:

text 复制代码
终端进程

├── HTTP_PROXY  ✅

├── HTTPS_PROXY ✅

└── ALL_PROXY   ✅




GNOME 启动的 ChatGPT

├── HTTP_PROXY  ❌

├── HTTPS_PROXY ❌

└── ALL_PROXY   ❌

      ↓

Codex app-server

├── HTTP_PROXY  ❌

├── HTTPS_PROXY ❌

└── ALL_PROXY   ❌

这时代理环境已经成为主要嫌疑。

六、为什么终端有代理,桌面图标启动的应用却没有

Linux 中的环境变量属于进程环境,通常由父进程传给子进程。

如果代理变量写在 .bashrc 等 Shell 配置中,启动链是:

text 复制代码
打开终端

    ↓

Bash 读取 .bashrc

    ↓

终端中出现 HTTP_PROXY 等变量

    ↓

从该终端启动的程序继承变量

但从 GNOME 应用菜单点击图标时,启动链通常是:

text 复制代码
GNOME 桌面

    ↓

.desktop 启动项

    ↓

ChatGPT

这里没有启动交互式 Bash,也不会自动读取 .bashrc。因此:

终端中的 env 能看到代理,不能证明整个桌面会话以及所有 GUI 应用都有这些变量。

普通 ChatGPT 对话仍能使用,可能是因为 Electron/Chromium 的网络服务还会读取系统代理,或者普通聊天与 Work 后端使用了不同的网络路径。但 Codex app-server 是独立的本地进程,它不一定使用 Chromium 的同一套代理机制。

七、决定性 A/B 测试:从终端启动 ChatGPT

在永久修改配置前,先做一次可逆的对照实验。

1. 完全退出当前 ChatGPT

bash 复制代码
pgrep -af '/usr/lib/chatgpt/ChatGPT'
  • pgrep:查找进程;

  • -a:显示完整命令行;

  • -f:按完整命令行匹配,而不只匹配进程名。

没有输出,说明旧进程已经退出。

2. 从已经具有代理变量的终端启动

bash 复制代码
/usr/lib/chatgpt/ChatGPT

此时父子关系变为:

text 复制代码
终端 / Bash

├── HTTP_PROXY

├── HTTPS_PROXY

└── ALL_PROXY

        ↓ 继承

ChatGPT

        ↓ 继承

Codex app-server

测试结果:

text 复制代码
从终端启动 ChatGPT → Work 正常

从 GNOME 图标启动 ChatGPT → Work 持续 Reconnecting

这是本次排障最有说服力的实验。除了启动来源和继承的环境变量外,账号、网络、系统、应用程序和测试目标均保持不变。

因此根因基本确认:

GNOME 图标启动的 ChatGPT 没有代理环境变量,导致其 Codex/Work 后端的外部请求超时。

八、找到 ChatGPT 的 .desktop 启动文件

Linux 桌面应用菜单背后通常使用 .desktop 文件,可以把它理解为带有标准字段的应用快捷方式。

常见字段包括:

ini 复制代码
[Desktop Entry]

Name=ChatGPT

Icon=chatgpt

Exec=chatgpt %U

Type=Application

其中:

  • Name=:菜单中显示的名称;

  • Icon=:应用图标;

  • Exec=:点击图标后实际执行的命令;

  • %U:Desktop Entry 规范中的 URL 参数占位符,不是 Shell 变量。

先按文件名寻找启动项:

bash 复制代码
find /usr/share/applications ~/.local/share/applications -type f \

  \( -iname '*chatgpt*.desktop' -o -iname '*codex*.desktop' \) 2>/dev/null

命令含义:

  • find:在目录树中寻找文件;

  • 两个路径:系统级与当前用户级应用启动目录;

  • -type f:只找普通文件;

  • -iname:按文件名匹配并忽略大小写;

  • -o:或者;

  • 2>/dev/null:隐藏无关的标准错误输出。

找到系统级文件:

text 复制代码
/usr/share/applications/chatgpt.desktop

读取关键字段:

bash 复制代码
grep -E '^(Name|Exec|Icon)=' /usr/share/applications/chatgpt.desktop

结果为:

text 复制代码
Name=ChatGPT

Exec=chatgpt %U

Icon=chatgpt

这就确认了,从 GNOME 图标启动时并没有显式附加代理环境变量。

九、为什么使用用户级覆盖,而不直接改系统文件

系统级启动项位于:

text 复制代码
/usr/share/applications/chatgpt.desktop

直接修改它存在两个问题:

  1. 需要管理员权限;

  2. ChatGPT 软件包升级时可能覆盖修改。

更稳妥的方法是复制到当前用户目录:

bash 复制代码
mkdir -p ~/.local/share/applications

cp /usr/share/applications/chatgpt.desktop ~/.local/share/applications/chatgpt.desktop
  • mkdir -p:确保用户级应用目录存在,已存在时不报错;

  • cp:复制系统启动文件;

  • 用户级同名启动项会优先于系统级启动项。

这种做法把修改限制在当前用户,也更容易回滚。

十、最终修复

编辑用户级启动项:

bash 复制代码
nano ~/.local/share/applications/chatgpt.desktop

把:

ini 复制代码
Exec=chatgpt %U

改为一整行:

ini 复制代码
Exec=/usr/bin/env HTTP_PROXY=http://127.0.0.1:7897 HTTPS_PROXY=http://127.0.0.1:7897 ALL_PROXY=socks://127.0.0.1:7897 NO_PROXY=localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,::1 chatgpt %U

/usr/bin/env 在这里的用法是:

text 复制代码
env 变量=值 变量=值 程序 参数

也就是:

只为这次启动的 ChatGPT 设置代理环境变量,然后运行 chatgpt %U

它不会把代理强行写给 Ubuntu 的所有程序,只影响由这个启动项启动的 ChatGPT 及其子进程。

变量作用:

  • HTTP_PROXY:HTTP 请求代理;

  • HTTPS_PROXY:HTTPS 请求代理;

  • ALL_PROXY:其他支持该变量的网络请求统一代理;

  • NO_PROXY:本机、局域网地址不走代理;

  • %U:保留原启动项接受 URL 参数的能力。

十一、验证修复

1. 检查用户级启动命令

bash 复制代码
grep '^Exec=' ~/.local/share/applications/chatgpt.desktop

应显示包含 HTTP_PROXYHTTPS_PROXYALL_PROXY 的完整启动命令。

2. 完全退出旧进程

先退出当前从终端启动的 ChatGPT,确保没有残留旧进程:

bash 复制代码
pgrep -af '/usr/lib/chatgpt/ChatGPT'

3. 从应用菜单重新启动

这次不要从终端启动,而是:

text 复制代码
Ubuntu 应用菜单 → ChatGPT 图标

然后进入 Work 执行最小测试。

实际结果:

text 复制代码
从桌面图标启动 → Work 恢复正常

这个功能测试已经验证修复成功。

4. 可选:检查运行进程环境

可以进一步找到正确的 ChatGPT 主进程 PID,再执行:

bash 复制代码
tr '\0' '\n' < /proc/codex进程PID/environ | grep -i proxy

十二、回滚方法

由于系统级启动项没有被修改,回滚非常简单。

bash 复制代码
rm ~/.local/share/applications/chatgpt.desktop

删除后,GNOME 会重新使用:

text 复制代码
/usr/share/applications/chatgpt.desktop

结论

本次 ChatGPT Work 持续 Reconnecting 并不是系统整体断网,也不是 Work 后端没有启动。

决定性证据是:同机网页版 Work 正常;桌面版失败;从带有 *** 代理环境变量的终端启动同一个 ChatGPT 程序后,Work 立即恢复。

根因是 GNOME 通过系统 .desktop 文件执行:

ini 复制代码
Exec=chatgpt %U

这一启动路径没有获得仅存在于 Shell 环境中的 HTTP_PROXYHTTPS_PROXYALL_PROXY。ChatGPT 启动的 Codex app-server 也无法继承这些变量,最终导致 Work 的部分外部请求约 30 秒后超时。

通过创建用户级 .desktop 覆盖,并使用 /usr/bin/env 为 ChatGPT 启动进程显式附加 *** 代理变量后,从 GNOME 图标启动的 Work 恢复正常。

这次排障最值得保留的 Linux 知识点是:

终端环境不是桌面环境;环境变量属于进程,并沿父子进程链继承。