VS Code 1.143.0 的 Linux deb 包装完以后,系统里会多出一个 /usr/bin/copilot,它是 VS Code 自带的一个小启动器,找不到 GitHub Copilot CLI 时会问你要不要装。企业用来关掉它的 CopilotCliCommand 策略只管“从 VS Code 安装”这一步,机器上已经装好的 Copilot CLI,通过这个命令照样能启动。另外策略改了以后,这个软链要等下一次 apt 配置包时才会被收走。
1.143.0 的 deb 包版本号是 1.143.0-1792533444,后面的时间戳换算过来是北京时间 10 月 21 日 05:57,更新接口现在给的 stable 最新版就是 1.143.0。官方发布说明里的大头是 Copilot harness 变成新会话默认、多模型对比(Preview)、清理 worktree 占用(Experimental)这些 Agent 相关的功能,上一版 1.142 的把聊天挪进新 worktree之前也写过。这次我关心的是发布说明最后一小节:Linux 安装包会把 copilot 可执行文件放进 PATH,运行时没装 Copilot CLI 就提示安装,装了就直接跑。这件事动的是系统目录,在共用的 Linux 开发机和 CI 镜像上更值得先弄清楚。
环境和做法
机器是 Debian 13 x86_64,JDK 21.0.12.1。我新建了一个普通用户 user,在 ~/demo 下用 start.spring.io 生成了一个只带 Web 依赖的 Spring Boot 4.1.1 项目,加一个返回字符串的 /hello 接口,./mvnw package 打包后跑起来能正常响应,后面的 copilot 命令都在这个项目目录里执行。安装用的是官方 deb 包,事先用 debconf 把“添加 Microsoft apt 源”设成 false,免得改动系统源。整个过程没有登录 GitHub,也没有调用任何模型。
先对比了两个版本的安装包。1.142.0 的 deb 解开后只有内置 Copilot 扩展的文件,没有 copilot-shim 目录,postinst 里也没有处理 /usr/bin/copilot 的代码。1.143.0 多了 /usr/share/code/bin/copilot-shim/copilot,是一个 700 多 KB 的 ELF 可执行文件,postinst 脚本里也多了一段专门维护 /usr/bin/copilot 的逻辑。tar.gz 包里同样带着这个文件,不过 tar.gz 不跑安装脚本,不会往 PATH 里放东西。
装完多了什么
$ code --version
1.143.0
2d0b7506a36c1d6db9a466440131a8e01eab2289
x64
$ type -a copilot
copilot is /usr/bin/copilot
copilot is /bin/copilot
$ readlink /usr/bin/copilot
/usr/share/code/bin/copilot-shim/copilot
$ copilot --vscode-shim policy; echo "exit=$?"
exit=0
$ copilot -p "summarize pom.xml" < /dev/null; echo "exit=$?"
GitHub Copilot CLI was not found. Run copilot in a terminal to install it, or see https://docs.github.com/en/copilot/how-tos/copilot-cli/set-up-copilot-cli/install-copilot-cli
exit=127
软链放在 /usr/bin,机器上每个用户的 PATH 里都有这个命令,并不只是装 VS Code 的那个人。没有终端(比如脚本里、CI 里、stdin 重定向)的时候它不会自作主张去装,只打一行提示,退出码 127,和 shell 里找不到命令时的退出码一样。--vscode-shim policy 是安装脚本自己用来读策略的子命令,返回 0 表示允许。
有终端时会问一次
用 script 模拟一个终端,先回答 n:
$ copilot # answer n
n
Installation instructions: https://docs.github.com/en/copilot/how-tos/copilot-cli/set-up-copilot-cli/install-copilot-cli
Install GitHub Copilot CLI? [y/N] exit=0
默认是 N,拒绝后什么都不装,退出码是 0。再来一次,这回带上 --version 参数并回答 y:
$ copilot --version # answer y
y
Installation instructions: https://docs.github.com/en/copilot/how-tos/copilot-cli/set-up-copilot-cli/install-copilot-cli
Install GitHub Copilot CLI? [y/N] Installing GitHub Copilot CLI...
Downloading from: https://github.com/github/copilot-cli/releases/latest/download/copilot-linux-x64.tar.gz
✓ Checksum validated
✓ GitHub Copilot CLI installed to ~/.local/bin/copilot
Installation complete! Run 'copilot help' to get started.
GitHub Copilot CLI 1.0.102.
Run 'copilot update' to check for updates.
exit=0
它下载的是 GitHub 上 copilot-cli 的 latest 发布包,校验和通过后装进当前用户的 ~/.local/bin,不需要 sudo,装完立刻把原来的 --version 参数转给真正的 CLI 执行。1.0.102 是 copilot-cli 仓库北京时间 10 月 22 日凌晨发布的版本。
装好以后,新开的登录 shell 里 ~/.local/bin/copilot 排在前面,会直接命中真正的 CLI。就算 PATH 里没有 ~/.local/bin,/usr/bin/copilot 也会到这个默认安装位置去找:
$ type -a copilot
copilot is ~/.local/bin/copilot
copilot is /usr/bin/copilot
copilot is /bin/copilot
$ PATH=/usr/bin:/bin copilot --version; echo "exit=$?"
GitHub Copilot CLI 1.0.102.
Run 'copilot update' to check for updates.
exit=0
$ copilot -p "summarize pom.xml" < /dev/null; echo "exit=$?"
Error: No authentication information found.
Copilot can be authenticated with GitHub using an OAuth Token or a Fine-Grained Personal Access Token.
To authenticate, you can use any of the following methods:
• Start 'copilot' and run the '/login' command
• Set the COPILOT_GITHUB_TOKEN, GH_TOKEN, or GITHUB_TOKEN environment variable
• Run 'gh auth login' to authenticate with the GitHub CLI
exit=1
最后一条是在 Spring Boot 项目目录里让它总结 pom.xml,因为没登录,Copilot CLI 自己报了认证错误,模型没有被调用。
CopilotCliCommand 策略管到哪一步
按企业 AI 设置文档,把 CopilotCliCommand 策略设成 false 就能关掉这个命令,Linux 上的策略文件是 /etc/vscode/policy.json。在还没装 Copilot CLI 的状态下写入策略:
$ cat /etc/vscode/policy.json
{ "CopilotCliCommand": false }
$ copilot --vscode-shim policy; echo "exit=$?"
exit=10
$ copilot -p "summarize pom.xml" < /dev/null; echo "exit=$?"
GitHub Copilot CLI was not found. Installing it from VS Code is turned off by the CopilotCliCommand policy; contact your administrator.
exit=10
$ ls -l /usr/bin/copilot
lrwxrwxrwx 1 root root 40 Oct 22 08:13 /usr/bin/copilot -> /usr/share/code/bin/copilot-shim/copilot
策略立刻生效,安装被拒,退出码变成 10。但软链还在。重新跑一次 apt-get install --reinstall,postinst 读到策略是关的,才把它删掉:
# sudo apt-get install --reinstall ./code_1.143.0_amd64.deb
Setting up code (1.143.0-1792533444) ...
ls: cannot access '/usr/bin/copilot': No such file or directory
所以先装 VS Code、后下发策略的机器,在下一次 VS Code 升级或重装之前,copilot 命令会一直在,只是装不了东西。
再看已经装好 Copilot CLI 的情况。同样写入 false 策略,绕开 ~/.local/bin 只走 /usr/bin/copilot:
$ cat /etc/vscode/policy.json
{ "CopilotCliCommand": false }
$ PATH=/usr/bin:/bin copilot --version; echo "exit=$?"
GitHub Copilot CLI 1.0.102.
Run 'copilot update' to check for updates.
exit=0
照样启动了。策略参考对 CopilotCliCommand 的说明是:关掉以后 VS Code 不再安装 Copilot CLI,集成终端里也不再提供这个命令,单独安装的 Copilot CLI 不受影响。启动器装的这份落在 ~/.local/bin,和 Copilot CLI 官方安装脚本给普通用户装的默认位置相同,对策略来说它就是一份已经装好的 CLI,所以不拦,这和文档的说法一致。文档另外提到,能不能用 Copilot CLI 由 GitHub 组织和企业设置决定,登录后才生效。
只想让 deb 包别碰 /usr/bin/copilot
deb 包为此加了一个 debconf 问题 code/add-copilot-command,默认 true,模板说明里写着 /etc/vscode/policy.json 里的策略优先。提前设成 false 再安装(或重装),软链就会被移除:
# echo "code code/add-copilot-command boolean false" | debconf-set-selections && apt-get install --reinstall
ls: cannot access '/usr/bin/copilot': No such file or directory
# debconf-show code
* code/add-copilot-command: false
* code/add-microsoft-repo: false
postinst 用 medium 优先级提这个问题,我这几次都是 DEBIAN_FRONTEND=noninteractive 安装,没有弹出询问,直接按预设值处理。
如果 /usr/bin/copilot 已经是别的东西,安装脚本不会覆盖。我手写了一个同名脚本放在那里,再把选项改回 true 重装:
# /usr/bin/copilot is a hand-written script; debconf true; apt-get install --reinstall
-rwxr-xr-x 1 root root 40 Oct 22 08:16 /usr/bin/copilot
my own copilot wrapper
脚本原样保留。postinst 只替换或删除指向 VS Code 自家两个启动器(stable 和 Insiders)的软链,其他文件一概不动。RPM 包没有 debconf,按脚本注释的说法,除非策略关掉,否则总会建这个命令,这部分我没有在 RPM 系统上跑。
一起交流
分享你的思考,让讨论更进一步。