报Permission denied是因为默认构建系统用./$file执行,需脚本有x权限;应改用"shell_cmd": "bash \"$file\"",仅需读权限且兼容语法。

Sublime Text 一键运行 Shell 脚本(Ctrl+B)报 Permission denied,不是构建系统写错了,而是它真正在尝试执行一个没权限的文件——但你完全没必要给脚本加 x 位或提权整个编辑器。
为什么 ./$file 会触发权限检查?
默认 Bash 构建系统常写成 "shell_cmd": "./$file",这等价于终端里敲 ./script.sh。Linux/macOS 严格校验该文件是否带可执行位(x),哪怕内容是合法 Bash 也不行。而 bash "$file" 只需读权限,绕过所有执行位限制。
- 终端验证:运行
ls -l script.sh,若输出是-rw-r--r--(无x),就必然失败 - 真正安全的写法是
"shell_cmd": "bash \"$file\"",双引号防路径空格,bash显式指定解释器 - 别用
sh "$file"测试——sh不支持[[ ]]、source或数组,会掩盖语法错误
WSL 用户必须改 shell_cmd 指向 bash
Windows 原生命令行不认 #!/usr/bin/env bash,WSL 用户若直接复用 Linux 构建配置,shell_cmd 仍走 Windows 的 cmd.exe 或 PowerShell,结果要么报错,要么静默忽略 # 行。
- 正确做法:在
Packages/User/Bash.sublime-build中明确写"shell_cmd": "wsl bash -x \"$file\"" - 确保 WSL 已启用且默认发行版为 Ubuntu/Debian(
wsl -l -v验证) - 避免用
cmd /c bash或powershell -c wsl——子进程环境丢失,$PATH和当前目录常错乱
atomic_save 和父目录权限会让运行“看起来成功”实则失败
构建系统输出面板显示 “Finished”,但脚本实际没跑?很可能是 Sublime 在保存时因权限问题静默失败,导致你 Ctrl+B 运行的是旧版本,甚至空文件。
- 检查
"atomic_save": true(默认)是否被拦截:WSL 的/mnt/c/、OneDrive 同步目录、NAS 挂载点普遍禁用rename()系统调用 - 父目录无写权限时,Sublime 先写
script.sh.tmp再rename,tmp 创建失败 → 保存无效 → Ctrl+B 运行的是未更新的旧内容 - 临时验证:菜单 →
Preferences → Settings,加一行"atomic_save": false,再试保存+运行
构建系统匹配不到文件?先看右下角语法和 selector
即使 Bash.sublime-build 配得再准,如果当前文件右下角显示的是 ShellScript 或 Plain Text,Sublime 根本不会加载该构建系统——它只靠 selector 字段匹配作用域。
- 必须手动设置语法:右下角点击 →
ShellScript → Bash(不是 “Shell Script”) - 确认构建系统中
"selector": "source.shell"(Bash 插件注册的实际作用域,非source.bash) - 文件未保存时
$file为空字符串,构建直接跳过;务必先Ctrl+S再运行
最易被忽略的是:你改了构建配置、设了 Bash 语法、也保存了文件,但右下角状态栏仍显示 “No build system”——说明 Tools → Build System 里选的还是 Automatic 或其他无关项,必须手动切到你刚保存的 Bash 项。


















