ChatGPT for macOS 不会读取终端中的 shell 配置。如果要在关闭系统代理和 TUN 模式时单独使用 Clash,可以通过启动参数指定代理,并将这条命令封装成独立的 macOS 应用。
生成代理启动器
下面的脚本会在 /Applications 中生成 ChatGPT Proxy.app。默认使用 Clash 的 7890 混合端口。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
| #!/bin/zsh
set -euo pipefail
PROXY_HOST="127.0.0.1"
PROXY_PORT="7890"
CHATGPT_APP="/Applications/ChatGPT.app"
TARGET_APP="/Applications/ChatGPT Proxy.app"
LAUNCHER_SCRIPT="$HOME/Desktop/chatgpt-proxy.applescript"
if [[ ! -d "$CHATGPT_APP" ]]; then
echo "未找到 $CHATGPT_APP" >&2
exit 1
fi
cat > "$LAUNCHER_SCRIPT" <<EOF
on run
set proxyHost to "${PROXY_HOST}"
set proxyPort to "${PROXY_PORT}"
set proxyURL to "http://" & proxyHost & ":" & proxyPort
set chatGPTApp to "${CHATGPT_APP}"
set mainExecutable to chatGPTApp & "/Contents/MacOS/ChatGPT"
try
do shell script "/usr/bin/nc -z " & quoted form of proxyHost & " " & quoted form of proxyPort
on error
display dialog "Clash 代理 " & proxyHost & ":" & proxyPort & " 未启动。" buttons {"好"} default button 1 with icon stop
return
end try
set chatGPTRunning to false
try
do shell script "/usr/bin/pgrep -f " & quoted form of ("^" & mainExecutable)
set chatGPTRunning to true
end try
if chatGPTRunning then
display dialog "请先退出正在运行的 ChatGPT,再打开 ChatGPT Proxy。" buttons {"好"} default button 1 with icon caution
return
end if
do shell script "/usr/bin/open -na " & quoted form of chatGPTApp & ¬
" --env " & quoted form of ("HTTP_PROXY=" & proxyURL) & ¬
" --env " & quoted form of ("HTTPS_PROXY=" & proxyURL) & ¬
" --env " & quoted form of ("ALL_PROXY=socks5://" & proxyHost & ":" & proxyPort) & ¬
" --env " & quoted form of "NO_PROXY=localhost,127.0.0.1,::1" & ¬
" --args " & quoted form of ("--proxy-server=" & proxyURL) & ¬
" " & quoted form of "--proxy-bypass-list=localhost;127.0.0.1;[::1]"
end run
EOF
rm -rf -- "$TARGET_APP"
/usr/bin/osacompile -o "$TARGET_APP" "$LAUNCHER_SCRIPT"
ICON_FILE="$CHATGPT_APP/Contents/Resources/icon-chatgpt.icns"
if [[ -f "$ICON_FILE" ]]; then
/bin/cp "$ICON_FILE" "$TARGET_APP/Contents/Resources/applet.icns"
fi
/usr/bin/codesign --force --deep --sign - "$TARGET_APP"
/usr/bin/touch "$TARGET_APP"
echo "已生成 $TARGET_APP"
|
如果 Clash 使用其他端口,修改脚本顶部的 PROXY_PORT。执行脚本后,先退出正在运行的 ChatGPT,再打开 /Applications/ChatGPT Proxy.app。
实现原理
启动器同时设置两组代理配置:
open --env 将 HTTP_PROXY、HTTPS_PROXY 和 ALL_PROXY 传给 ChatGPT 及其子进程。--proxy-server 将代理地址传给 Chromium 网络层。
--proxy-bypass-list 让本机地址保持直连。启动器每次运行时还会检查 Clash 端口和 ChatGPT 进程,避免在代理未启动或已有实例运行时继续执行。
验证
检查 ChatGPT 主进程是否收到代理参数:
1
2
3
| ps axww -o pid=,command= \
| grep "/Applications/ChatGPT.app/Contents/MacOS/ChatGPT" \
| grep -- "--proxy-server=http://127.0.0.1:7890"
|
检查 ChatGPT 是否连接到 Clash:
1
2
3
4
5
| CHATGPT_PID="$(pgrep -f '^/Applications/ChatGPT.app/Contents/MacOS/ChatGPT .*--proxy-server=' | head -n 1)"
for pid in "$CHATGPT_PID" $(pgrep -P "$CHATGPT_PID"); do
lsof -nP -a -p "$pid" -iTCP 2>/dev/null
done | grep -- "->127.0.0.1:7890"
|
出现到 127.0.0.1:7890 的 ESTABLISHED 连接,即表示 ChatGPT 已通过 Clash 联网。