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.

2 Answers 2

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"

Using Bash:

for a in volume1/photoTest/*
      pushd "$a"/eaDir_tmp
      cp -u * ../@eaDir          #... or rsync --chmod...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .