You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过ls管道输出给rsync失败:含指定关键词文件夹备份问题

解决rsync无法接收grep输出作为输入的问题

嘿,我来帮你搞定这个rsync同步的问题!你遇到的核心问题是rsync默认不会从标准输入(管道)读取要同步的文件/文件夹列表,而且你的命令写法也有几个小问题,我一步步给你拆解和修正。

为什么你的原有命令失效?

你之前的命令 ls -d $PWD/** | grep March | rsync -av 'dst' 有两个关键问题:

  1. rsync的语法搞反了:你把dst放在了源的位置,rsync的正确格式是rsync [选项] 源 目标,这里你没指定源,反而把目标当成了源,自然没效果。
  2. rsync默认不读取管道输入:要让它从stdin获取源列表,必须用--files-from=-参数(-表示从标准输入读取)。

另外你用xargs -0的尝试也不对,因为ls的输出是换行分隔的,而-0是告诉xargs用null字符作为分隔符,两者不匹配,反而会把所有内容当成一个参数,导致同步失败。

正确的解决方案

方案1:用rsync的--files-from=-直接读取管道列表

这是最直接的方法,让rsync从stdin获取要同步的文件夹路径:

# 先确保bash开启了globstar(支持**递归匹配)
shopt -s globstar
ls -d "$PWD"/** | grep March | rsync -av --files-from=- . dst/
  • --files-from=-:告诉rsync从标准输入读取要同步的路径列表
  • .:因为你的列表是绝对路径,这里用.作为源基准(rsync需要一个源目录参考,绝对路径的话这个参数不影响,但必须写)
  • dst/:目标文件夹,末尾加/表示把源文件夹的内容同步到dst目录下;如果不加/,会在dst下创建和源同名的文件夹再同步内容。

方案2:用xargs逐个同步文件夹

如果你的文件夹名称包含空格、特殊字符,用xargs配合-I {}更安全,它会把管道的每一行作为单独的参数:

shopt -s globstar
ls -d "$PWD"/** | grep March | xargs -I {} rsync -av {} dst/
  • -I {}:将管道输入的每一行替换为{},然后执行后面的rsync命令,每个文件夹单独同步。

更安全的替代:用find命令替代ls+grep

解析ls的输出其实有风险——如果文件夹名包含空格、换行或特殊字符,ls的输出会被拆分,导致错误。更靠谱的方式是用find直接筛选目标文件夹:

# 方法1:配合rsync的--files-from
find "$PWD" -type d -name "*March*" | rsync -av --files-from=- . dst/

# 方法2:配合xargs的null分隔(完美处理特殊字符)
find "$PWD" -type d -name "*March*" -print0 | xargs -0 -I {} rsync -av {} dst/
  • -type d:只匹配文件夹
  • -name "*March*":筛选名称包含March的文件夹
  • -print0:用null字符分隔输出,配合xargs -0可以完美处理包含空格、换行的文件名。

关键注意事项

  • 确保开启globstar:如果用**递归匹配子文件夹,需要先执行shopt -s globstar(bash默认可能没开启)
  • 目标路径的结尾/:决定了同步的方式,加/是把源内容放到目标文件夹里,不加是在目标下创建源同名文件夹再同步
  • 避免解析ls输出:特殊字符会导致各种奇怪的问题,优先用find命令。

内容的提问来源于stack exchange,提问作者Morten

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:23:34