花拾录
← 返回知识库

用 SFTP 往 NAS 上传文件,连临时目录都报"文件不存在"

云计算 / 运维导入2026/09/220 阅读0 评论

你写好了一个部署脚本,准备把打包好的文件通过 SFTP 传到 NAS 上,再去目标机器安装。结果第一步就卡住了:连往临时目录写文件都失败,报的还是"文件不存在"。你 ls 一下,目录明明就在那里,看得见、进得去,可就是写不进去。

现象

  • 用 SFTP 往 NAS 上传文件,连临时目录都写不进去;
  • 报错信息说文件不存在(File not found / No such file);
  • 但用同一个连接列目录却完全正常,目录真实存在。

"目录存在,却跟你说文件不存在"——这个矛盾本身就是线索:它在用"不存在"作为拒绝的方式。

根因

根因是:这台 NAS 的 SFTP 子系统禁止写入,而它拒绝写入时给出的错误是"文件不存在",而不是"权限被拒"。

很多 NAS 设备的 SFTP(SSH 文件传输子系统)是按只读设计的。它们面向的是"浏览、下载、备份读取"这类场景,出于安全考虑(防止通过 SFTP 往系统里塞文件)直接把写操作禁掉了。当你的写请求进来,它没法真的创建一个文件,于是回了一个语义上最接近"这里没有你要操作的东西"的错误——文件不存在。

这属于错误信息误导:真实原因(不允许写)和报出来的信息(不存在)指向了完全不同的排查方向。如果你顺着"路径是不是写错了""文件名有没有问题"去查,会一直查不到点,因为路径和文件名都是对的。

要区分清楚两种"写不进去":

  • 文件权限不足:目录存在但没有写权限,报的是 Permission denied;
  • 功能被禁用:整个 SFTP 写通道被关掉,报的可能是"文件不存在"这类含糊信息。

这台 NAS 属于后者。

解决

思路:绕开被禁用的 SFTP 写通道,改用 SSH 命令通道落盘。

SFTP 只是 SSH 的一个子系统。写不了,不代表整条 SSH 通道不能用。 只要 SSH 能执行命令,就可以用命令把内容写进去。一条常用做法是:把内容 base64 编码后,经 SSH 命令通道解码落盘——base64 只用 ASCII 字符,能安全穿过命令行的引号、换行等转义问题。

# 1. 本地把文件内容 base64 成一行
B64=$(base64 -w0 ./deploy.tar.gz)

# 2. 经 SSH 命令通道传到远端并解码落盘
ssh <用户>@<IP> "echo '$B64' | base64 -d > /tmp/deploy.tar.gz"

# 3. 校验两端哈希一致(重要)
# 本地
sha256sum ./deploy.tar.gz
# 远端
ssh <用户>@<IP> "sha256sum /tmp/deploy.tar.gz"

落在临时目录后,再用 sudo 安装到目标位置:

ssh -t <用户>@<IP> "sudo mv /tmp/deploy.tar.gz /目标目录/"

几个要点:

  • base64 用 -w0,去掉换行,否则一行拆成多行会在远端 echo 时出问题。
  • 内容很大时,命令行长度有限制,base64 传输适合中小文件;大文件考虑用 scp/rsync(如果它们可用)或分段传输。
  • 务必校验哈希。传输 + 解码 + shell 转义,任何一步出错都可能让文件静默损坏。sha256sum 两端一致,才算真的到齐了。

如果远端连 SSH 命令通道都受限,那就只能换传输方式(U 盘、HTTP 上传接口等),但多数 NAS 至少保留了 SSH 命令执行能力。

延伸与预防

这条坑的通用教训是:报"不存在"的错误,也可能是"不允许"。

排查时不要被错误信息的字面意思牵着走。当"目录明明存在却说文件不存在"这类矛盾出现时,先怀疑权限或功能限制,而不是路径拼写:

  1. 换个角度验证。ls 能列、write 不能写,指向的就是"只读限制",而不是路径问题。
  2. 换通道验证。SFTP 不行时试试 SSH 命令执行、scp、HTTP 接口——一个通道被关,往往还有别的通道开着。
  3. 区分"权限位"和"功能开关"。两者都表现为"拒绝",但一个改权限位能解,另一个得换方法。

一句话:当错误信息和事实矛盾时,相信事实,重新推断错误信息真正的含义。

评论(0)

  • 还没有评论,来抢沙发~

相关文章