$file展开为当前已保存文件的绝对路径,未保存时为空字符串;$file_path是文件所在目录的绝对路径(不含尾部斜杠),未保存或无项目时均为空。

Sublime构建系统里$file变量到底展开成什么
$file 展开为当前文件的**绝对路径**,但前提是文件已保存。如果标签页显示 Untitled,$file 就是空字符串——命令直接执行失败或静默退出,比如 ["python", ""]。这不是 Sublime 的 bug,而是设计如此:它不读内存内容,只操作磁盘上的真实文件。
- 验证方式:在 Python 文件中写
import os; print(os.path.abspath(__file__)),和sys.executable一起运行,对比输出 - 相对路径无法自动解析:
./script.py或../lib/helper.py这类写法在cmd数组里不会被展开,Sublime 不做 shell 解释 - 想用相对路径导入模块?靠的是 Python 运行时的
sys.path和当前工作目录,不是构建系统本身
working_dir字段才是控制相对路径行为的关键
构建系统里 "working_dir": "$file_path"(即文件所在目录)是默认且最常用设置。它决定了 os.getcwd() 返回值、open("data.txt") 找文件的位置,以及 import 时相对导入的基准目录。
-
$file_path是文件所在目录的绝对路径,不含尾部斜杠;未保存文件时也为空 - 若项目结构是
project/src/main.py和project/data/config.json,设"working_dir": "$project_path"才能让main.py里的open("data/config.json")成功 -
$project_path仅在存在 .sublime-project 文件时有效;单文件无项目时该变量为空,不能 fallback - Windows 下路径含空格时,
working_dir不需要引号,但必须是合法路径字符串(如C:/my project)
为什么shell_cmd里写相对路径大概率失败
用 "shell_cmd": "python ./script.py" 是危险操作。Windows 的 cmd.exe 不识别 $file 变量,./script.py 会被当成字面量,而当前工作目录又未必是你期望的——结果就是 python: can't open file './script.py': [Errno 2] No such file or directory。
- ✅ 安全写法永远用
"cmd": ["python", "-u", "$file"]:Sublime 自动拼接参数,天然兼容空格、跨平台、路径转义 - ❌
shell_cmd在 Windows 上几乎不可靠:不支持变量展开、&&失效、含空格路径必须手动加引号且易出错 - macOS/Linux 下
shell_cmd虽能跑,但依赖 shell 环境,PATH混乱时会调错解释器(比如本想用 venv 里的 python,却跑了系统默认的)
多级子目录下运行脚本时的路径陷阱
假设你有 app/backend/api/handler.py,里面写了 from utils.db import connect,而 utils/ 在 app/utils/。此时光靠 working_dir 不够,得让 Python 知道怎么找包。
- 方案一:在构建系统里加
"path": "/full/path/to/app",这样sys.path开头就会多一个路径 - 方案二:用
"cmd": ["python", "-u", "-m", "backend.api.handler"],配合"working_dir": "$project_path",走模块方式启动(要求app是包,含__init__.py) - 方案三:在脚本开头硬编码
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..")),但污染逻辑,不推荐 - 注意:
path字段只影响子进程环境变量PATH,对 Python 的sys.path无效——别指望它解决ModuleNotFoundError
$file_path 和 $project_path 都不保证存在,它们的值取决于用户是否保存了文件、是否打开了项目。没有 fallback 机制,配置写死就等于放弃健壮性。**

















