我的文件夹结构是这样的:
/volume1
/photoTest
/folderA
/@eaDir
/eaDir_tmp
/folderB
/@eaDir
/eaDir_tmp
/folder with space
/@eaDir
/eaDir_tmp
我想做的是将文件从每个文件夹复制eaDir_tmp
到各自的@eaDir
文件夹中。
我能够通过以下方式让它进行:
for a in $(find /volume1/photoTest -type d -name eaDir_tmp); do rsync -vhar --chmod=a+rwx $a/ $a/../@eaDir; done;
直到我点击带有空格的文件夹。上面的脚本简直就是废话。
经过大量谷歌搜索后,我尝试了:
find /volume1/photoTest -type d -name eaDir_tmp -print0 | xargs -0 rsync -vhra --chmod=a+rwx {} {}/../@eaDir
该命令的试运行运行没有问题。但打印后实际运行就卡住了。
sending incremental file list
@eaDir/subdir1/
并卡在其上。
ps -elf | grep rsync
显示一堆 rsync 进程的开启wait
和poll_s
状态。
有人知道发生了什么事吗?解决方案可能是什么?我想最终移动文件,但首先尝试复制,以便在出现问题时减少破坏性。
另外,我可以使用两个命令来让它工作,但有很多丑陋的地方:
# first, copy all files via:
find /volume1/photo -type d -name eaDir_tmp -exec cp -a -t {}/../@eaDir {}/. \;
# second, change file permissions:
find /volume1/photo -type d -name @eaDir -exec chmod 777 {} -R \;
但这很慢并且需要两倍的时间,更不用说与 rsync 可以做的相比非常有限。
一些背景信息:
- 文件夹里面有什么
eaDir
?更多文件夹,然后是其中的一些文件。如果有帮助的话,整个事情是这样开始的:https://github.com/mbrrg/synology-thumbgen。作者建议删除现有@eaDir
文件夹并简单地重命名eaDir_tmp
.但我不能这样做,因为现有文件夹包含我想保留的文件。我可以解释,但我认为这会使问题进一步混乱。 - 这是在我的 Synology NAS DSM 6.0+ 内,我认为它正在运行 BusyBox?但不确定。
- 如果目标文件存在,那么如果源文件较新,我想覆盖它。否则不会。
答案1
find /volume1/photoTest -type d -name eaDir_tmp -prune \
-exec sh -c 'rsync -a "$1"/ "${1%/*}/@eaDir"' sh {} ';' \
-o -type d -name @eaDir -prune
这将查找名称eaDir_tmp
位于 或之下的所有目录/volume1/photoTest
。对于每个这样的目录,将执行以下命令:
rsync -a "$1"/ "${1%/*}/@eaDir"
其中$1
是找到的目录的路径名。参数替换${1%/*}
将删除路径名的最后一个组成部分,将 eg 变成/volume1/photoTest/folderA/eaDir_tmp
(/volume1/photoTest/folderA
您也可以使用"$( dirname "$1" )"
)。
eaDir_tmp
当我们找到任何找到的内容和目录时,我们会@eaDir
从搜索列表中删除它们,并停止find
输入它们。这是用 完成的-prune
。
与find
接受-execdir
:
find /volume1/photoTest -type d -name eaDir_tmp -prune \
-execdir rsync -a eaDir_tmp/ @eaDir ';' \
-o -type d -name @eaDir -prune
有关的:
使用zsh
:
for dirpath in /volume1/photoTest/*/eaDir_tmp(/DN); do
rsync -a "$dirpath"/ "$dirpath:h/@eaDir"
done
使用bash
:
shopt -s dotglob nullglob
for dirpath in /volume1/photoTest/*/eaDir_tmp/; do
rsync -a "$dirpath"/ "$(dirname "$dirpath")/@eaDir"
done
答案2
使用重击:
for a in volume1/photoTest/*
do
pushd "$a"/eaDir_tmp
cp -u * ../@eaDir #... or rsync --chmod...
popd
done