My folder structure is like this:

    /folder with space

What I'm trying to do is copy files from each eaDir_tmp to their respective @eaDir folder.

I was able to get it going via:

for a in $(find /volume1/photoTest -type d -name eaDir_tmp); do rsync -vhar --chmod=a+rwx $a/ $a/../@eaDir; done;

until I hit the folder with spaces. The above script simply craps out.

After lots of googling, I tried:

find /volume1/photoTest -type d -name eaDir_tmp -print0 | xargs -0 rsync -vhra --chmod=a+rwx {} {}/../@eaDir

Dry run of this command runs without issues. But the actual run gets stuck after printing this.

sending incremental file list

And gets stuck thereon.

ps -elf | grep rsync shows bunch of rsync processes on wait and poll_s state.

Does anyone have any idea what's going on? And what the solution might be? I would like to move files eventually, but trying with copy first to be less destructive if things go bad.

Also, I can get it working with 2 commands with lots of ugliness:

# 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 \;

But this is slow and takes twice the time, not to mention is very limiting compared to what rsync can do.

Some background info:

  • What's inside eaDir folders? More folders, and then some files inside them. If it helps, the whole thing started with this: https://github.com/mbrrg/synology-thumbgen. The author suggests to delete existing @eaDir folders and simply rename eaDir_tmp. But I can't do that because existing folders contains files that I'd like to keep. I can explain but I think that'll muddy the question further.
  • This is inside my Synology NAS, DSM 6.0+, which I think is running BusyBox? Not sure though.
  • If destination files exists, then I'd like to overwrite it if source is newer. Otherwise not.

Using Bash:

for a in volume1/photoTest/*
      pushd "$a"/eaDir_tmp
      cp -u * ../@eaDir          #... or rsync --chmod...
find /volume1/photoTest -type d -name eaDir_tmp -prune \
    -exec sh -c 'rsync -a "$1"/ "${1%/*}/@eaDir"' sh {} ';' \
    -o -type d -name @eaDir -prune

This would look for all directories whose name is eaDir_tmp in or under /volume1/photoTest. For each such directory, the following command would be executed:

rsync -a "$1"/ "${1%/*}/@eaDir"

where $1 is the pathname of the found directory. The parameter substitution ${1%/*} would remove the last component of the pathname, turning e.g. /volume1/photoTest/folderA/eaDir_tmp into /volume1/photoTest/folderA (you could also use "$( dirname "$1" )").

We remove any found eaDir_tmp and @eaDir directory from the search list when we find them, stopping find from entering them. This is done with -prune.

With a find that accepts -execdir:

find /volume1/photoTest -type d -name eaDir_tmp -prune \
    -execdir rsync -a eaDir_tmp/ @eaDir ';' \
    -o -type d -name @eaDir -prune


Using zsh:

for dirpath in /volume1/photoTest/*/eaDir_tmp(/DN); do
    rsync -a "$dirpath"/ "$dirpath:h/@eaDir"

Using bash:

shopt -s dotglob nullglob
for dirpath in /volume1/photoTest/*/eaDir_tmp/; do
    rsync -a "$dirpath"/ "$(dirname "$dirpath")/@eaDir"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.