我手上这台 Ubuntu 从 20.04 一路滚到 24.04 LTS中间重装过三次硬件换过两轮唯一没变的是写代码的窗口永远是 VSCode代码跑的地方永远是那台 Ubuntu。原因很朴素——VSCode 的 Remote-SSH 把“编辑在本地、运行在远端”这件事的摩擦压到了几乎为零界面响应是本地机器的速度编译、跑测试、起服务用的却是 Linux 的工具链和文件系统。Vscode 连接 Ubuntu 这件事网上教程一大把但绝大多数只告诉你点哪个按钮不告诉你为什么这么点、点错了会怎样。这篇我想按一个真实的开发节奏来写从方案取舍、环境准备、配置细节到连不上时怎么一层层往下扒尽量把每个“为什么”说清楚让刚上手的新同学和有几年经验的老手都能各取所需。1. 先把连接方案想明白别急着装插件1.1 本地虚拟机、双系统、远端主机三种载体的真实成本很多人一上来就问“怎么连”但更该先问的是“Ubuntu 跑在哪”。这个选择决定了后面 80% 的坑在哪儿。我把常见的三种载体拉成一张表这些都是我自己或同事真实用过的组合。载体硬件门槛隔离性折腾成本适合谁虚拟机VMware / VirtualBox中内存最好 16G 起高快照随便回滚低装完就能用学习、验证、跑不熟的命令双系统高需要空闲分区低共用硬件中高分区和引导有风险需要显卡、外设直通的场景独立主机 / 远端服务器高要额外设备或费用最高中网络配置要动脑长期开发、跑训练任务虚拟机最大的价值不是省钱是快照。你准备动/etc/environment这种一不小心就把图形界面搞挂的文件时先在 VMware 里拍一张快照出事了三十秒回滚比你在那儿翻救援教程高效得多。我早期就是因为没有这个习惯改错一次 PATH 之后花了两个小时才进回桌面。双系统适合什么适合你需要真实显卡性能、需要 USB 直通、需要跑只有裸机才能跑的驱动的场合。代价是分区操作不可逆动手前务必把重要数据备份到外部介质这是唯一没有商量余地的步骤。1.2 Remote-SSH、WSL、Dev Containers 到底选哪个VSCode 官方给远程开发提供了好几条路名字都带 Remote但解决的问题完全不同。Remote-SSH是这次的主角VSCode 在你本地跑界面后端进程一个叫 vscode-server 的东西跑在远端 Ubuntu 上。你敲的每一行代码通过网络传过去编译、执行、调试全在远端发生。它的关键优势是文件系统零拷贝——大仓库不用同步到本地改完直接就是远端磁盘上的内容。WSL是 Windows 用户的捷径本质是 Windows 里跑了一个轻量 Linux 内核VSCode 用 WSL 扩展直接连进去完全不走网络所以速度最快、配置最少。代价是它是子系统不是完整发行版systemd 支持、内核模块、部分网络行为都有差异。Dev Containers走的是另一条路把一个 Docker 容器当开发环境。它的核心卖点是“环境即代码”devcontainer.json一提交团队里每个人打开都是同一套工具链版本。做多人协作、CI 和本地环境要求完全一致的团队这个方案收益最大。我的实际组合是这样的主力开发走 Remote-SSH 连独立 Ubuntu临时验证一些不想污染主机的命令开 WSL给团队新人的项目标配一个 Dev Container 配置。三者不冲突各管一段。2. Ubuntu 端的地基这些没做好后面全是玄学2.1 系统安装路线与分区大小的算法如果你还没装系统建议直接上 Ubuntu 24.04 LTS 桌面版从官方渠道拿 ISO下载完顺手校验一下哈希避免镜像损坏导致的安装中途报错。虚拟机参数我一般这么配CPU 给 4 核内存给 8G磁盘给 60G 并选“拆分多个文件”。理由很直接——现在的编译器、Docker 镜像、Node 依赖动辄几个 G磁盘给到 40G 以下两三个月就红。双系统的分区则要算一下。根分区/给 40G 到 60G因为 apt 缓存和 Docker 默认都在这里/home给剩下的绝大部分你的代码、配置、缓存都在里面将来重装系统时可以只格式化/而保留/home这是双系统最大的隐藏福利。交换分区 swap 的算法是物理内存小于等于 8G 的给内存的 1.5 到 2 倍16G 以上的给 8G 或者干脆用文件形式的 swap 就够了因为日常开发很少真的把 16G 内存跑满再溢出。装完之后有个习惯一定要养成先跑一次sudo apt update sudo apt upgrade再开始装任何开发工具。系统刚装好的时候源列表是最新的隔几周再用旧索引装包很容易出现依赖版本对不上的情况。2.2 装 SSHD让 Ubuntu 愿意接你的敲门Ubuntu 桌面版默认不装 OpenSSH 服务端所以你在 VSCode 里怎么连都是Connection refused。第一步永远是装服务端。sudo apt update sudo apt install -y openssh-server sudo systemctl enable --now ssh systemctl status ssh看到active (running)才算成功。接下来改配置我通常只动几个关键项sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak sudo vi /etc/ssh/sshd_config# 监听端口默认 22想改就改 Port 22 # 禁止 root 直接登录这个必须保持 no PermitRootLogin no # 允许公钥登录 PubkeyAuthentication yes # 密码登录先开着配好密钥后再关掉 PasswordAuthentication yes # 空闲连接保活避免长时间不操作被断开 ClientAliveInterval 60 ClientAliveCountMax 3改完必须重启服务改注释不会自动生效sudo systemctl restart ssh。改配置的时候有个细节要注意Ubuntu 的 sshd 在sshd_config.d/目录下还会加载额外的片段文件某些安装方式会往里面塞默认配置如果你改了主文件却没反应先去看看这个目录里有没有覆盖项。2.3 网络模式怎么定IP 去哪找这一步是新手翻车最集中的地方。虚拟机里跑 Ubuntu 的话网络模式有三种选择NAT、桥接、仅主机。NAT 模式是默认选项虚拟机通过主机的网络出去好处是换个 Wi-Fi 也不用改配置坏处是主机之外的机器访问不到虚拟机你必须在这个模式下配置端口转发把主机的 2222 端口转发到虚拟机的 22 端口然后 SSH 连的是127.0.0.1:2222而不是虚拟机的 IP。我见过太多人在这卡住就是因为拿着一个 192.168.x.x 的地址去连结果当然是超时。桥接模式让虚拟机直接出现在你所在的局域网里有自己的 IP主机和其他设备都能直连配置更直觉。代价是网络环境一变比如从家里换到公司IP 就可能变甚至出现桥接不到的情况。仅主机模式只有主机能连隔离性最好适合你完全不想让别人碰到这台开发机。在 Ubuntu 里查自己的 IP两个命令就够ip addr show | grep inet hostname -I如果你想要一个固定的 IPUbuntu 现在用 netplan 管理网络配置文件在/etc/netplan/下network: version: 2 ethernets: ens33: dhcp4: no addresses: - 192.168.1.100/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: [192.168.1.1, 8.8.8.8]改完用sudo netplan try而不是直接apply因为try会在 120 秒后自动回滚万一配错了你不会失去连接。这个细节我强烈建议记住尤其是远程主机上操作网络配置的时候那是真正的救命功能。2.4 gcc、cmake、docker 装不上时的稳妥路径基础工具链用一条命令解决sudo apt install -y build-essential gdb git curl。build-essential里包含 gcc、g、make 这些装完之后gcc --version能出版本号就说明没问题。如果这一步报错八成是源的问题或者包索引坏了先试sudo apt --fix-broken install再不行就换一个软件源镜像重试。CMake 有个常见的版本陷阱。Ubuntu 仓库里的 CMake 版本通常比较保守比如 24.04 给的是 3.28 左右。如果你要编译的项目里写了cmake_minimum_required(VERSION 3.30)那就会直接报错退出。查版本用cmake --version需要更高版本时有两条路一是从 Kitware 官方的 apt 源装最新稳定版二是用 pip 装一个用户级的 cmakepip install --user cmake注意这个方式可能在 PATH 顺序上出问题。我一般选前者因为它是系统级的行为最可预测。Docker 我建议按官方文档的仓库方式装而不是用apt install docker.io因为仓库版的版本更新更快sudo apt install -y ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg echo deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release echo $VERSION_CODENAME) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io装完记得把自己的用户加进 docker 组否则每条命令都要 sudosudo usermod -aG docker $USER注意加组之后必须重新登录才生效很多人加完立刻测试还是权限报错就是忽略了这一点。另外能免 sudo 跑 docker 等价于拥有 root 权限生产机器上要谨慎对待。3. VSCode 端Remote-SSH 从零跑通的完整路径3.1 插件安装与 SSH config 的正确写法在 VSCode 扩展面板搜Remote - SSH认准 Microsoft 发布的那个装。装完之后左侧会出现“远程资源管理器”。关键的一步是配置~/.ssh/config。很多人习惯在命令面板里手输userhost能用但不好维护尤其当你同时连三台机器的时候。写进配置文件一次搞定Host ubt-dev HostName 192.168.1.100 User devuser Port 22 IdentityFile ~/.ssh/id_ed25519 ServerAliveInterval 30 ServerAliveCountMax 6 TCPKeepAlive yesServerAliveInterval 30加ServerAliveCountMax 6的意思是每 30 秒发一次心跳连续 6 次没回应也就是 3 分钟才判定断开。这个组合对笔记本合盖、Wi-Fi 抖动特别有用能省掉大量“刚写完一段代码连接断了”的崩溃时刻。Windows 下的路径是C:\Users\你的用户名\.ssh\config注意这个文件没有扩展名用资源管理器新建时要小心别变成config.txt。这个坑我踩过命令行里ssh ubt-dev死活不认最后发现是隐藏了扩展名导致的。3.2 密钥登录把密码这一关彻底关掉密码登录的问题是每连一次都要输而且密码在网络上传输始终是额外风险。密钥登录一次性配好之后就是无感连接。# 本地机器上执行ed25519 比 rsa 更短更安全 ssh-keygen -t ed25519 -C devlaptop # 一路回车默认路径即可密码短语可以留空也可以设 ssh-copy-id -i ~/.ssh/id_ed25519.pub devuser192.168.1.100如果ssh-copy-id不可用比如 Windows 环境手动上传也行cat ~/.ssh/id_ed25519.pub | ssh devuser192.168.1.100 mkdir -p ~/.ssh cat ~/.ssh/authorized_keys ssh devuser192.168.1.100 chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys权限这一串是必须的SSH 的安全检查很严格~/.ssh给 700authorized_keys给 600~目录本身不能对组和其他用户可写。如果/home/devuser的权限是 777你会看到Permission denied (publickey)然后怀疑人生。确认密钥能免密登录之后回到服务端配置把PasswordAuthentication改成no再sudo systemctl restart ssh。3.3 连上之后的第一件事搞清远端扩展和本地扩展连上远端之后扩展面板会分成“本地”和“SSH: ubt-dev”两组。这个区分极其重要Python、C/C、CMake 这类扩展必须装在远端因为它们要调用远端的解释器、编译器和调试器而主题、字体、快捷键、Markdown 预览这类纯界面扩展装在本地就够了装到远端只是浪费磁盘。我见过有人抱怨远端 VSCode 慢一查是几十个界面类扩展全装在远端每次连接都要在远端启动一堆进程。正确的做法是打开扩展面板切到远端标签页只留真正需要远端能力的那些。至于打开项目一定要点“打开文件夹”然后选/home/devuser/项目名这种 Linux 路径别选挂在/mnt下的 Windows 盘符路径。原因后面第 7 节会细说。4. 让环境真正干活C/C、Python、CMake 的实操配置4.1 C/C 三件套编译、调试、智能提示在远端装好C/C扩展注意是远端标签页里装之后在项目下建.vscode目录放三个文件。c_cpp_properties.json负责智能提示和头文件路径{ configurations: [ { name: Linux, includePath: [ ${workspaceFolder}/**, /usr/include, /usr/local/include ], defines: [], compilerPath: /usr/bin/g, cStandard: c17, cppStandard: c20, intelliSenseMode: linux-gcc-x64 } ], version: 4 }tasks.json负责编译{ version: 2.0.0, tasks: [ { label: build-debug, type: shell, command: /usr/bin/g, args: [ -g, -O0, -Wall, -Wextra, ${file}, -o, ${fileDirname}/${fileBasenameNoExtension} ], group: { kind: build, isDefault: true }, problemMatcher: [$gcc] } ] }launch.json负责调试{ version: 0.2.0, configurations: [ { name: gdb launch, type: cppdbg, request: launch, program: ${fileDirname}/${fileBasenameNoExtension}, args: [], stopAtEntry: false, cwd: ${workspaceFolder}, environment: [], externalConsole: false, MIMode: gdb, setupCommands: [ { description: 开启美化打印, text: -enable-pretty-printing, ignoreFailures: true } ], preLaunchTask: build-debug } ] }这里-g -O0是调试的基本要求尾部没加优化变量才不会被优化掉导致断点处的值显示成optimized out。preLaunchTask绑定编译任务按 F5 时会先编译再进调试这个联动是提升效率的关键。如果你做的是嵌入式方向的开发比如 Zephyr 这类 RTOS 项目思路是一样的只是compilerPath要换成交叉编译工具链里的arm-zephyr-eabi-gccincludePath里补上 Zephyr 的 include 目录launch.json要换成cortex-debug这类专用调试扩展通过 OpenOCD 连调试器。这三件套的结构不变换的只是工具名。4.2 Python 解释器切换与虚拟环境远端开发 Python 的第一件事是装齐全套sudo apt install -y python3 python3-pip python3-venv。注意python3-venv这个包Ubuntu 默认不装缺了它你python3 -m venv会直接报错这个报错信息还挺误导人的。虚拟环境是必须的别在系统 Python 里直接 pip 装东西cd ~/projects/demo python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt然后在 VSCode 里按CtrlShiftP选Python: Select Interpreter选中./.venv/bin/python。之后Run and Debug和终端都会自动用这个解释器。这里有个 Ubuntu 24.04 上的特有坑PEP 668 之后直接用 pip 往系统环境装包会报error: externally-managed-environment。这个设计是保护系统包管理器的完整性不要用--break-system-packages去绕过它正确做法就是老老实实用虚拟环境。绕过它当时很爽等到某次系统升级冲突的时候就知道代价了。4.3 CMake 项目的目录规范与版本匹配一个最小可用的CMakeLists.txtcmake_minimum_required(VERSION 3.16) project(demo LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_executable(demo src/main.cpp) target_include_directories(demo PRIVATE include)构建时永远用 out-of-source 方式也就是单独开一个build目录别在源码目录里cmake .cmake -S . -B build -DCMAKE_BUILD_TYPEDebug cmake --build build -j$(nproc)-S指定源目录、-B指定构建目录这种写法在 CMake 3.13 之后才支持如果你在维护老项目用mkdir build cd build cmake ..更保险。-j$(nproc)是并行编译用满 CPU 核心大项目能省一大半时间。CMAKE_BUILD_TYPE也要注意不指定的话默认是空相当于没优化也没调试符号很多人调不出断点就是因为这个。装CMake Tools扩展之后VSCode 底部会出现构建按钮和配置选择器CMakePresets.json还能把常用参数固化成预设团队共享特别方便。5. 中文环境与终端体验把别扭感消掉5.1 VSCode 汉化和几条我必改的设置汉化很简单扩展面板搜Chinese (Simplified)装完重启如果没自动生效就CtrlShiftP输入Configure Display Language选zh-cn。真正影响效率的是几条设置我在settings.json里长期保留{ files.autoSave: onFocusChange, editor.formatOnSave: true, editor.tabSize: 4, editor.rulers: [100], files.watcherExclude: { **/node_modules/**: true, **/.git/objects/**: true, **/build/**: true, **/.venv/**: true }, remote.SSH.remotePlatform: { ubt-dev: linux } }files.watcherExclude这条在远端开发里价值特别高后面第 6 节会解释原因。remote.SSH.remotePlatform是明确告诉 VSCode 远端是 Linux避免它每次都去探测能省几秒连接时间。5.2 Ubuntu 中文输入法为什么我最后选了 fcitx5Ubuntu 上配中文输入法历史包袱挺多。老教程会让你装 fcitx 加搜狗输入法但在 24.04 上搜狗依赖的老库和系统自带版本容易打架表现为输入法状态栏出不来、或者敲字的时候整个窗口卡住。我的建议是直接用 fcitx5 加自带的拼音方案稳定性和维护活跃度都更好。sudo apt install -y fcitx5 fcitx5-chinese-addons fcitx5-frontend-gtk3 fcitx5-frontend-gtk4 fcitx5-frontend-qt5 im-config -n fcitx5然后设置环境变量这一步是关键很多人装完输入法重启还是不生效就是没配这些cat ~/.xprofile EOF export GTK_IM_MODULEfcitx export QT_IM_MODULEfcitx export XMODIFIERSimfcitx export SDL_IM_MODULEfcitx export GLFW_IM_MODULEibus EOF写完之后注销重新登录然后运行fcitx5-configtool添加拼音输入法。如果你用的是 Wayland 会话情况会稍微不同环境变量的作用范围有限一般需要在系统设置的键盘布局里直接添加输入源。判断自己在哪个会话echo $XDG_SESSION_TYPE输出wayland还是x11一眼就知道。在 VSCode 里如果遇到输入法候选框位置偏移或者打不出字先检查是不是装了 Vim 类插件正在插入模式下拦截按键这个坑非常隐蔽我自己找了半小时才发现。5.3 终端乱码、字体和默认 shell终端里出现乱码九成是 locale 没配好。检查一下locale如果LANG是空的或者显示POSIX就会出现中文文件名显示成问号的情况。修复sudo apt install -y locales sudo locale-gen zh_CN.UTF-8 en_US.UTF-8 sudo update-locale LANGen_US.UTF-8我一般把系统 LANG 设成en_US.UTF-8而不是中文因为很多命令行工具输出中文提示反而不利于搜索报错信息中文显示能力由 UTF-8 编码提供就够了两者不冲突。终端字体建议装一个带图标字形的等宽字体Nerd Font 系列是社区里的通用选择。默认 shell 如果想换成 zsh记得用chsh -s $(which zsh)而不是直接改/etc/passwd改错了会导致登录后立刻掉线。换完之后跟 Remote-SSH 有关的一个注意点VSCode 集成终端启动的是非交互式 shell某些只写在.bashrc里的环境变量它读不到需要放到.profile或.bash_profile里这是第 6.2 节要展开的问题。6. 连不上的时候按这条链路往下扒6.1 SSH 故障速查表先给一张对照表基本上能覆盖九成情况。现象最可能的原因第一步动作Connection refusedsshd 没启动或端口不对systemctl status ssh、ss -tlnp | grep 22Connection timed out网络不通、NAT 没做端口转发、防火墙拦截ping、ufw status、检查虚拟机网络模式Permission denied (publickey)密钥没配上、权限过宽、用户不对客户端ssh -v看用了哪个密钥Host key verification failedknown_hosts 里有旧主机指纹ssh-keygen -R 主机名连上但卡在 Setting up远端负载高或网络带宽不足看远端top、换有线网络能连但 VSCode 报锁文件错误上次异常退出的 vscode-server 残留删掉远端~/.vscode-server重连排查的黄金命令是加-vssh -vvv devuser192.168.1.100它会打印握手全过程卡在哪一步一目了然。如果Connecting to ... port 22之后就没了说明是网络层的问题如果走到Authentications that can continue: publickey才失败那问题就在密钥或权限上。这个分界线非常有用能把排查范围直接砍一半。远端侧的检查清单systemctl status ssh sudo ss -tlnp | grep :22 sudo ufw status verbose tail -n 50 /var/log/auth.logufw status如果在虚拟机环境里是 active 状态记得放行sudo ufw allow 22/tcp。另外有些环境里ss显示监听在127.0.0.1:22而不是0.0.0.0:22那就说明 sshd 的 ListenAddress 被限制成只监听本地了外部当然连不上。如果你习惯用 Xshell、PuTTY 这类客户端做网络连通性验证思路完全一样先确认能 telnet 通 22 端口再谈 VSCode 的事。把“网络能不能通”和“认证能不能过”分开验证是排障最重要的方法论。6.2 环境变量配置错误的典型表现与急救这是最容易把系统搞挂的一类操作我把它单独拎出来说。最常见的错误是覆盖 PATH 而不是追加。写了export PATH/usr/local/bin这种后果是整台机器所有系统命令都找不到包括ls、vi、sudo。正确写法永远是export PATH$PATH:/opt/mytool/bin$PATH:这个前缀不能少。第二个坑是改错文件。/etc/environment是给整个系统登录会话用的语法是KEYvalue不能写export也不能写 shell 函数。写错了可能导致图形界面登录直接失败转一圈回到登录页。而~/.bashrc只对交互式非登录 shell 生效~/.profile对登录 shell 生效。VSCode 的 Remote-SSH 后端启动方式比较特殊它读取的环境往往是登录会话的所以你在.bashrc里加的变量在集成终端里能echo出来但 Python 调试器里就是读不到——这个现象很多人遇到过根因就在这里。如果不幸把系统变量搞坏了导致图形界面进不去急救方法是按CtrlAltF3切到 TTY用完整路径调用编辑器/usr/bin/sudo /usr/bin/vi /etc/environment注意必须用绝对路径因为 PATH 已经废了。改回来之后CtrlAltF1或者重启回图形界面。这也是为什么我前面反复强调虚拟机要拍快照的原因——有快照这一步就完全不需要了。6.3 远端卡顿、文件不刷新、端口转发的处理远端 VSCode 卡顿通常有三个来源。第一个是文件监听。Linux 用 inotify 监听文件变化而每个用户的监听句柄数有上限默认值通常是 8192 到 65536 之间遇到node_modules这种几万文件的目录直接就爆了表现出来就是文件树不刷新、搜索不到新文件。临时调整cat /proc/sys/fs/inotify/max_user_watches sudo sysctl fs.inotify.max_user_watches524288 echo fs.inotify.max_user_watches524288 | sudo tee -a /etc/sysctl.conf从根上解决还是靠第 5.1 节里那份files.watcherExclude把build、.venv、node_modules这些目录从监听范围里排除掉省下来的句柄够用很久。第二个来源是远端本身资源紧张。远端内存被编译过程吃满之后ssh 会话响应会明显变慢甚至断连。开一个top或者htop盯着内存编译时用-j2而不是-j$(nproc)牺牲一点速度换稳定性。第三个是网络。跨国或者跨机房的链路普通 SSH 交互还行但 VSCode 的扩展通信量大延迟高的时候体验会很差。这种情况可以考虑在远端跑一个 code-server 用浏览器访问或者在链路稳定的时候做开发。另外 VSCode 的端口转发功能很实用远端起了个 8000 端口的服务VSCode 会自动检测并在“端口”面板里提示点一下转发本地浏览器就能直接访问localhost:8000不用手动做 SSH 隧道。如果你用的是带独立显卡的机器做深度学习顺便说一句显卡驱动的检查方式nvidia-smi能出表格说明驱动正常出不了就用ubuntu-drivers devices看推荐驱动版本再通过“软件和更新”里的附加驱动页面选中安装。装完驱动不要立刻装 CUDA 全套先确认nvidia-smi正常再按需安装运行时能少走很多弯路。7. 把效率再往上提一档的插件与习惯7.1 我的插件清单按用途分类用途插件装在哪一侧远程连接Remote - SSH、Remote Explorer本地C/C 开发C/C、CMake Tools、Error Lens远端Python 开发Python、Pylance、Ruff远端容器与编排Docker远端文档写作Markdown All in One、Markdown Preview Enhanced本地版本管理GitLens本地规范统一EditorConfig for VS Code本地实时协作Live Share本地AI 辅助主流的 AI 代码补全类扩展按需AI 辅助这块现在的形态大概分两种一种是纯扩展形式在 VSCode 里直接提供补全和对话另一种是命令行工具加扩展的组合CLI 装在 Ubuntu 远端扩展在本地负责展示。第二种形态要注意CLI 必须装在远端才能访问远端的代码和工具链装在本地是无效的。另外在远端跑 AI 相关工具注意一下磁盘占用和网络流量有些工具会在项目目录下生成索引缓存动辄几个 G。Error Lens 这个插件值得单独提一句它把编译器和语言服务器的诊断信息直接显示在代码行尾不用把鼠标移上去才能看到。对 C 这种报错信息一堆的场合能省掉大量来回点击的时间。7.2 设置同步与多机协同打开Settings Sync之后VSCode 会把你的设置、快捷键、扩展列表同步到账号下。这里有个细节默认同步的是本地扩展远端扩展的列表跟在每个远端的~/.vscode-server里换了一台新的远端机器远端扩展还是要重装一遍。我一般用一个extensions.txt记录远端必装列表新机器上跑一条命令批量装cat extensions.txt | xargs -L 1 code --install-extension配合~/.ssh/config也同步过去换机器的成本能压到十分钟以内。7.3 几条踩坑之后固化下来的习惯第一条永远不要用 root 用户做日常开发。用 root 意味着你rm -rf的时候没有任何缓冲也意味着文件权限会变成一团乱麻之后普通用户改不了自己的项目。用普通用户加 sudo 组合安全性高得多。第二条项目代码放在/home下不要放在/mnt挂载的 Windows 或共享目录里。跨文件系统的文件监听不可靠权限模型也不一样表现出来就是热重载失效、文件改动不同步、git 操作莫名其妙报权限错误。我在这个问题上浪费过整整一个下午。第三条长时间跑的任务编译、训练、批量脚本放在 tmux 里跑不要直接放在 VSCode 的集成终端里。VSCode 一旦断连或者崩溃集成终端里的进程会跟着挂掉而 tmux 会话不受影响重连之后tmux attach就回来了。第四条动/etc下的任何配置文件之前先复制一份带.bak后缀的备份这条规则看起来笨但救过我的次数早就数不清了。配合虚拟机快照使用基本上可以做到敢于折腾。第五条把系统的语言环境、软硬件记录成一份自己的初始化脚本。重装系统这件事有脚本和没脚本的差距大概是两小时对二十分钟。上面这整套配置我整理成了一个 shell 脚本重装之后跑一遍从装包到写 SSH 配置再到装远端扩展全部自动化。我个人这几年最深的体会是VSCode 连 Ubuntu 这套组合真正的门槛不在某一步配置上而在于你是否理解每一层在做什么网络层决定能不能通认证层决定能不能进会话层决定进去之后环境对不对扩展层决定体验顺不顺。把四层分开看任何一个问题都能在几分钟内定位混在一起看就会变成“不知道为什么就是连不上”的玄学。上面这些配置我到现在还在用中间改过的只有端口号和几台机器的别名骨架一直没动过说明这套东西在长期维护这件事上是站得住的。
