VSCode 的 launch.json 不支持 shell 变量动态解析,仅支持 ${env:VAR}、${workspaceFolder} 等预定义变量;args 必须为 JSON 数组且各参数独立,env 不支持链式引用,调试需通过“运行和调试”侧边栏启动才生效。

VSCode 无法直接在 launch.json 中动态解析 shell 变量(如 ${MODEL} 或 $CUDA_VISIBLE_DEVICES),所有 args 和 env 字段值都是静态字符串,不经过 shell 展开。所谓“动态传递”,实际是靠 VSCode 的变量替换机制(如 ${env:VAR}、${input:xxx})或外部脚本间接实现。
launch.json 里哪些变量能用、哪些不能用
VSCode 支持有限的预定义变量,但它们不是 shell 变量,也不能嵌套或运算:
-
${env:PATH}:读取系统/会话环境变量,启动 VSCode 前就得设好(比如终端中export MODEL=bert再运行code .) -
${workspaceFolder}、${file}、${fileBasenameNoExtension}:路径类变量,安全可靠 -
${input:xxx}:需配合inputs数组定义交互式输入,适合调试时手动选参数 -
${config:python.defaultInterpreterPath}:读取 settings.json 配置项,不能读取任意配置 - ❌
${MODEL}、$DATA、`date +%s`:这些 shell 语法完全无效,会被原样传给 Python 脚本,导致参数错乱
args 参数必须写成数组,不能拼接成字符串
常见错误是把多个参数写成一个字符串,比如 "args": ["--model bert --data /tmp"]——这会让 Python 的 argparse 只收到一个长参数,而非两个独立参数。
正确写法必须拆成独立字符串元素:
立即学习“Python免费学习笔记(深入)”;
{
"name": "Train with args",
"type": "python",
"request": "launch",
"program": "train.py",
"args": [
"--model_name",
"bert",
"--data_path",
"${workspaceFolder}/data/train",
"--batch_size",
"8"
],
"env": {
"CUDA_VISIBLE_DEVICES": "0"
}
}
注意:args 是 JSON 数组,每个参数单独一项;路径类值推荐用 ${workspaceFolder} 而非硬编码,避免换机器失效。
env 环境变量不支持引用其他 env 变量
你不能写 "CUDA_VISIBLE_DEVICES": "${env:CUDA_DEVICE_ID}"——VSCode 不支持 env 变量链式引用。如果需要多层控制,有两个现实选择:
- 在操作系统层面提前设置好最终变量(如
export CUDA_VISIBLE_DEVICES=1),再用${env:CUDA_VISIBLE_DEVICES}读取 - 改用
inputs+${input:xxx}实现调试时选择,例如定义一个下拉输入让 GPU ID 可选 - 对复杂逻辑(如根据模型名自动选 GPU),建议放弃
launch.json直接管理,改用 Python 包装脚本(如run_debug.py)做判断和转发
调试时参数不生效?先确认你点的是哪个按钮
这是最常被忽略的执行路径问题:
- ✅ 正确:打开“运行和调试”侧边栏 → 选配置 → 点绿色三角 ▶️(或按
F5)→ 完全走launch.json - ❌ 错误:编辑器右上角的“▶️ 运行 Python 文件”按钮 → 它绕过
launch.json,只执行python xxx.py,args和env全部丢弃 - ⚠️ 注意:
"console": "integratedTerminal"仅控制输出位置,不影响参数是否传递
如果参数始终不生效,第一反应不是改配置,而是检查这个按钮来源——90% 的“参数没传进去”问题出在这里。
真正动态的参数组合(比如不同数据集+不同超参+不同 GPU)不适合塞进 launch.json 硬编码。要么用 inputs 做有限交互,要么交给包装脚本处理。别试图用变量嵌套或外部命令注入来“曲线救国”,VSCode 的变量机制没那么灵活,强行折腾只会让配置越来越难维护。


















