rsync 目标目录不存在时怎么用 --mkpath 自动创建路径
首次把构建产物同步到新服务器时,最常见的阻塞不是文件不存在,而是远端目标路径还没有建好。rsync 可以用 --mkpath 自动创建目标路径中缺失的各级目录,最小写法如下:
# --mkpath 让接收端创建缺失的目标目录,源端末尾 / 表示同步目录内容 rsync -av --mkpath ./dist/ deploy@example.com:/srv/apps/releases/2026-10-13/
官方手册把它定义为创建目标路径中缺失的路径组件,语义接近在接收端执行 mkdir -p。它解决的是“目录链不存在”,并不会替远端账号获得父目录的遍历权或写权限。
官方地址:https://rsync.samba.org/ftp/rsync/rsync.1
记住三点:用--mkpath创建缺失目录,用目标末尾的/明确目录语义,再用远端实际登录用户检查父目录权限。权限不足时,继续添加参数也不会解决问题。
--mkpath 到底创建了什么
假设接收端原来只有 /srv,而 /srv/apps/releases/2026-10-13/ 整条路径都不存在。执行上面的目录同步命令时,rsync 会在接收端补齐缺少的 apps、releases 和 2026-10-13,然后把 dist/ 中的内容放进去。
这里的关键是“目标路径的缺失组件”,不是把源端的目录树原样复制到任意位置。--mkpath 只负责让目标路径可落地,文件是否更新仍然由 rsync 的同步规则决定。

目录同步时,两个斜杠要分清
目录同步最稳妥的写法是源路径和目标路径都保留末尾斜杠:
# 源端 dist/ 的内容进入目标目录,不额外包一层 dist rsync -av --mkpath ./dist/ deploy@example.com:/srv/apps/releases/2026-10-13/
源端的 dist/ 表示“复制目录内容”;如果写成 ./dist,通常会把目录本身作为传输树的一层,结果可能变成目标下出现 dist/。目标端的末尾 / 则明确告诉 rsync:最后一段是目录,不要因为只有一个源项目而把它解释成目标文件名。
目标路径缺少中间目录时,--mkpath 才是本题的关键;单纯补一个目标末尾斜杠只能表达目录意图,不能替代创建缺失目录。

单个文件也可以直接落到新路径
部署脚本只上传一个归档文件时,可以把最终文件名写完整:
# 目标最后一段是文件名;--mkpath 负责创建它上面的父目录 rsync -av --mkpath ./build/app.tar.gz deploy@example.com:/srv/apps/releases/2026-10-13/app.tar.gz
这种写法的前提是源列表只有一个文件,并且目标最后一段不是已经存在的目录。若你的意图是把文件放进一个目录,而不是改名为某个文件,建议把目录写成带末尾斜杠的形式:
# 目录语义明确:文件名会保留在目标目录中 rsync -av --mkpath ./build/app.tar.gz deploy@example.com:/srv/apps/releases/2026-10-13/
权限报错时先看远端登录用户
--mkpath 创建目录的动作发生在接收端。远端 SSH 用户必须同时满足两个条件:
- 能够逐级进入已经存在的父目录,也就是对路径上的目录拥有执行权限;
- 对需要创建下一级目录的父目录拥有写权限。
因此,下面两条命令适合在远端排查目标路径的责任边界:
# 查看当前 SSH 用户,避免把本机账号误当成远端账号 id # 从已有父目录开始检查是否能遍历并写入 namei -l /srv/apps/releases/2026-10-13
如果远端账号只能写入自己的发布目录,就把目标改到该账号拥有的目录;不要为了让 rsync 成功而直接扩大整棵目录树的权限。若目标位于受限目录,应该由管理员预先创建父目录并授予最小必要权限。
脚本里怎样保持首次运行和重复运行一致
把目标目录集中成一个变量,并始终使用同一条命令,可以避免首次运行时靠手工 ssh mkdir,后续又忘记同步参数:
#!/usr/bin/env bash set -euo pipefail # 统一发布目标,首次运行时由 --mkpath 创建缺失路径 target='deploy@example.com:/srv/apps/releases/2026-10-13/' # 源端使用目录内容语义,重复运行仍由 rsync 判断需要更新的文件 rsync -av --mkpath ./dist/ "$target"
如果脚本需要让新建目录的属性尽量跟随发送端目录,而不是只创建一条可用路径,可以进一步研究官方手册提到的相对路径用法;但这已经是目录属性策略,不是 --mkpath 的基本职责。
常见误区速查
| 现象 | 原因 | 处理 |
|---|---|---|
| 中间目录不存在 | 默认只会处理最终目标组件 | 增加 --mkpath |
| 目标多出一层 dist | 源路径没有使用内容语义 | 目录内容同步时写成 dist/ |
| 文件被当成目录名或改名结果不对 | 单文件目标的最后一段语义不明确 | 目录目标加末尾 /,改名时写完整文件路径 |
| Permission denied | 远端用户不能遍历或写入父目录 | 用远端用户检查路径权限,预先准备最小权限 |
结论
rsync 目标目录不存在时,优先使用 --mkpath 处理多级路径创建;同步目录时保留源端和目标端的末尾斜杠,单文件上传时明确最终文件名。遇到权限错误,就回到接收端的登录用户、父目录遍历权和写权限,而不要把路径问题误判成传输参数问题。
相关问题
- 为什么 rsync 加了
--mkpath仍然提示 Permission denied? - 源目录后面的斜杠会不会改变远端最终目录层级?
- 上传单个文件时,目标路径什么时候应该保留末尾斜杠?
- 怎样确认 rsync 实际使用的是哪个远端账号?
SSH ControlPath 怎么避免不同主机复用同一个 socket
- 上一篇
- SSH ControlPath 怎么避免不同主机复用同一个 socket
- 下一篇
- ssh-add -h 怎么限制转发密钥只能用于指定主机
-
- 文章 · linux | 1小时前 |
- rsync 覆盖旧文件前怎么用 --backup-dir 留存变更版本
- 344浏览 收藏
-
- 文章 · linux | 1小时前 | Linux · rsync --max-delete rsync --delete rsync 删除保护 Linux 镜像同步
- rsync 删除文件过多时怎么用 --max-delete 保护目标目录
- 321浏览 收藏
-
- 文章 · linux | 1小时前 |
- ssh-add -h 怎么限制转发密钥只能用于指定主机
- 268浏览 收藏
-
- 文章 · linux | 1小时前 |
- SSH ControlPath 怎么避免不同主机复用同一个 socket
- 446浏览 收藏
-
- 文章 · linux | 2小时前 |
- udevadm settle 怎么用设备文件作为提前结束条件
- 197浏览 收藏
-
- 文章 · linux | 2小时前 | Linux · 故障排查 · udevadm settle udev事件队列 udevadm timeout Linux设备事件
- udevadm settle 超时退出时怎么判断设备事件是否还没处理完
- 394浏览 收藏
-
- 文章 · linux | 2小时前 | linux运维 · Linux 文件清理 dry-run tmpfiles.d systemd-tmpfiles
- systemd-tmpfiles 清理前怎么用 dry-run 看将要删除的路径
- 342浏览 收藏
-
- 文章 · linux | 2小时前 | Linux · tmpfiles.d systemd-tmpfiles Linux临时文件
- tmpfiles.d 的用户级配置和系统级配置有什么区别
- 160浏览 收藏
-
- 文章 · linux | 2小时前 | Linux systemd 配置优先级 tmpfiles.d 配置排查 systemd-tmpfiles --cat-config
- systemd-tmpfiles --cat-config 怎么查看最终采用的配置片段
- 411浏览 收藏
-
- 文章 · linux | 2小时前 | linux运维 · Linux 软件包卸载 tmpfiles.d systemd-tmpfiles
- systemd-tmpfiles --purge 怎么清理软件包创建的运行目录
- 340浏览 收藏
-
- 文章 · linux | 2天前 | linux运维 · Linux 日志清理 磁盘空间 journalctl systemd-journald
- journalctl vacuum-size 清理日志的保留策略
- 328浏览 收藏
-
- 文章 · linux | 2天前 |
- OpenSSH ControlMaster 复用连接的失效原因
- 278浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 456次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 521次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 536次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 484次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 304次使用
-
- 百度网盘怎么自动备份手机照片?和同步盘、分享文件有什么区别
- 2026-07-15 489浏览
-
- 详解golang执行Linuxshell命令完整场景下的使用方法
- 2023-01-07 426浏览
-
- go程序部署到linux上运行的实现方法
- 2023-01-02 387浏览
-
- Linux系统下Go语言开发环境搭建
- 2023-01-07 242浏览
-
- 使用golang获取linux上文件的访问/创建/修改时间
- 2022-12-31 238浏览

