在Bash脚本中使用rsync本地移动文件时,含空格文件名的文件无法复制的问题求助
解决rsync处理带空格文件名的问题
我来帮你搞定这个困扰!你的问题根源在于用反引号展开find结果时,Bash会自动按空格、制表符或换行符分割输出,导致带空格的文件名被拆成多个零碎的参数,rsync自然无法识别这些不存在的“文件”。下面给你几个靠谱的解决方案,按推荐程度排序:
方法1:用find的-exec直接调用rsync(最简便高效)
直接让find把找到的文件作为完整参数传给rsync,完全避免文件名分割问题:
find "$sourcepath" -daystart -mtime 2 -type f -exec rsync -avhs --protect-args --remove-source-files --info=progress2 {} + "$bavkuppath"
-exec {} +会把所有找到的文件批量传递给rsync(比每次调用一次rsync的-exec {} \;高效很多){}会被替换成每个完整的文件名,包括带空格的,find会自动处理参数边界- 记得给
$sourcepath和$bavkuppath加上双引号,防止路径本身带空格时出问题
方法2:用print0 + xargs -0 传递文件名
通过null字符作为文件名分隔符,彻底规避空格的影响:
find "$sourcepath" -daystart -mtime 2 -type f -print0 | xargs -0 rsync -avhs --protect-args --remove-source-files --info=progress2 --files-from=- "$bavkuppath"
-print0让find用null字符(而不是换行/空格)分隔文件名xargs -0告诉xargs用null字符分割输入参数--files-from=-让rsync从标准输入读取要同步的文件名列表
方法3:用Bash数组存储文件名(适合需要额外处理文件的场景)
如果你的脚本需要先对找到的文件做其他操作,可以把文件名存入Bash数组,再传递给rsync:
#!/bin/bash # 开启nullglob,避免数组为空时输出无效参数 shopt -s nullglob # 用循环读取find输出的null分隔文件名,存入数组 files=() while IFS= read -r -d '' file; do files+=( "$file" ) done < <(find "$sourcepath" -daystart -mtime 2 -type f -print0) # 传递数组给rsync,数组展开时会保留每个文件名的完整性 rsync -avhs --protect-args --remove-source-files --info=progress2 "${files[@]}" "$bavkuppath"
"${files[@]}"会把数组中的每个元素作为独立的参数传递,完美保留带空格的文件名
最后再提醒一句:所有路径变量(比如$sourcepath、$bavkuppath)都要用双引号括起来,否则只要路径里有空格,同样会触发分割问题。
内容的提问来源于stack exchange,提问作者Satyam Mishra
相关产品推荐
相关产品推荐

