远程终端默认使用 bash 而非 zsh 是因为其 shell 由远程主机 /etc/passwd 中的登录 shell 决定,vscode 本地配置 terminal.integrated.defaultprofile.* 等完全无效;必须在远程机器用 chsh 修改用户登录 shell 并彻底重连 ssh。

远程终端启动时为什么总是用 bash 而不是 zsh
VSCode 远程连接(SSH 或 Dev Container)后,终端默认 shell 由远程主机的 /etc/passwd 中该用户的登录 shell 决定,**不是** VSCode 本地设置或 terminal.integrated.defaultProfile.* 控制的。很多人误以为改本地 settings.json 就能生效,结果远程终端依然启动 bash —— 因为那套配置只影响本地终端。
如何让远程终端真正使用 zsh(或其他 shell)
必须在远程机器上确保用户登录 shell 已设为目标 shell。验证和修改方法如下:
- 登录远程主机,运行
echo $SHELL:输出应为/bin/zsh(或你期望的路径),否则说明登录 shell 未变更 - 检查当前登录 shell:
getent passwd $USER | cut -d: -f7,返回值必须匹配目标 shell 路径 - 若不匹配,用
chsh -s /bin/zsh修改(需有权限;部分托管环境如 GitHub Codespaces 不允许执行chsh) - 修改后需**完全退出并重连 SSH 连接**(仅重启 VSCode 窗口或终端标签页无效)
Dev Container 场景下 shell 配置的特殊处理
使用 .devcontainer/devcontainer.json 时,remoteEnv 和 postStartCommand 都不能改变登录 shell。唯一可靠方式是:
- 在
Dockerfile或features中显式设置用户 shell,例如:RUN chsh -s /bin/zsh node
(注意替换为实际用户名) - 或在
devcontainer.json的initializeCommand中写入 shell 切换逻辑(仅限支持交互式chsh的镜像) - 更稳妥的做法:在
/root/.bashrc或/home/vscode/.profile末尾加exec zsh -l(适用于无法修改 login shell 的只读镜像)
为什么改了 terminal.integrated.profiles.linux 没用
这个设置只在「本地 Linux 终端」中生效。VSCode 远程扩展启动的终端进程,本质是通过 SSH 执行 login -f <user></user>(或类似机制),完全绕过 VSCode 的 profile 配置。常见误操作包括:
- 在远程窗口的
settings.json里写"terminal.integrated.defaultProfile.linux": "zsh"→ 无效果 - 把
shellArgs设成["-i", "-l"]→ 只影响子 shell 启动参数,不改变登录 shell 本身 - 依赖
process.env.SHELL在 JS 中动态切换 → 远程终端进程不读取 VSCode 渲染进程的环境变量
真正的控制点永远在远程系统的用户账户层面,而不是编辑器配置里。











