SFTP保存失败根源在远程权限、路径或配置:remote_path错误、远程目录缺w/x权限、SSH StrictModes导致降级只读、upload_on_save未匹配路径映射,或preserve_modification_times在NFS/容器中需设为false。

Sublime Text 3 的 SFTP 插件保存失败,几乎从来不是插件本身坏了,而是它在远程服务器上尝试写入时被拒绝——你看到的“Permission denied”或静默失败,根源在 SSH 权限、远程路径所有权或 SFTP 配置细节上。
为什么 SFTP 保存后文件没更新,也不报错?
这是 SFTP 最典型的假成功现象:插件显示“Upload completed”,但远程文件内容未变。常见原因包括:
-
remote_path配置错误,实际上传到了另一个目录(比如少了个/导致路径拼接异常) - 远程用户对目标目录没有
w(写)和x(执行/进入)权限——SFTP上传需先mkdir临时目录或重命名,缺x就卡住 - 服务器启用了
StrictModes on(OpenSSH 默认开启),而你的~/.ssh/authorized_keys文件权限是644或属主不对,导致 SSH 连接降级为密码认证,SFTP 会静默回退到只读模式 -
sftp_config.json中设了"upload_on_save": true,但没配"sync_down_on_open": false,本地改完自动上传,却因远程文件被其他进程(如 nginx、pm2)占用而失败,且不提示
检查远程目录权限和属主的实操步骤
别只看文件权限,SFTP 保存依赖整条路径可写可进:
- 用终端登录服务器,运行:
ls -ld /var/www/html—— 如果输出是dr-xr-xr-x,说明目录不可写;drwxr-xr-x才合格 - 确认当前 SSH 用户对目录有写权:
touch /var/www/html/test.tmp && rm /var/www/html/test.tmp,失败就说明权限或 SELinux(Linux)/AppArmor 拦截了 - 检查父目录属主:
ls -ld /var/www,如果属主是root:root,普通用户无法在其中创建子目录;应改为:sudo chown -R $USER:www-data /var/www/html(Ubuntu/Debian)或sudo chown -R $USER:nginx /var/www/html(CentOS) - 避免用
chmod 777:它会让 Web 服务直接暴露可写目录,很多 CMS(如 WordPress)因此被黑
SFTP 配置里最容易踩坑的三个字段
sftp_config.json 看似简单,但三个字段配错就会让保存行为完全失控:
-
"type": "sftp"必须明确,不能漏;如果误写成"ftp"或留空,插件会 fallback 到本地文件系统,看似“保存成功”,实则根本没传 -
"save_before_upload": true是默认值,但如果你关了它,又没手动 Ctrl+S,修改后直接 Cmd+Alt+U 上传,就会传旧内容——建议保持开启 -
"preserve_modification_times": false在某些 NFS 或容器挂载的远程路径上必须设为false,否则上传后因时间戳同步失败,插件会回滚操作且不报错
用 sshfs 临时替代 SFTP 调试更直观
当 SFTP 行为难以追踪时,绕过插件直连更利于定位:
- macOS/Linux:运行
sshfs user@host:/var/www/html ~/mnt/remote -o follow_symlinks,然后把 Sublime 工作区直接打开~/mnt/remote目录 - 此时保存等同于本地写入,任何权限错误(如
Operation not permitted)都会立刻弹出系统级报错,比 SFTP 的静默失败好排查得多 - 成功后,再对比
sshfs的挂载参数(如-o allow_other、-o uid=501)反推 SFTP 配置缺了什么
真正难的不是让 SFTP “能上传”,而是让它“传得稳、改得准、错得明”。很多团队后期放弃 SFTP 插件,不是因为功能弱,而是配置项分散在 SSH 层、文件系统层、Web 服务层三处,漏查一层就白调半天。最省事的方式,其实是把开发机的 /var/www 改成用户可写目录,再用 rsync --delete 配合 git hook 同步,反而比实时 SFTP 更可靠。










