1

I hacked together this script to rsync some files over ssh. The --remove-source-files option of rsync seems to remove the files it transfers, which is what I want. However, I also want the directories those files are placed in to be gone as well.

The current part of the find command, -exec rmdir -p {} ; tries to remove the parent directory (in this case, /srv/torrents), but fails because it doesn't have the right permissions. What I'd like to do is stop rmdir from traversing above the directory find is run in, or find another solution to get rid of all the empty folders. I've thought of using some kind of loop with find and running rmdir without the -p switch, but I thought it wouldn't work out.

Essentially, is there an alternative way to remove all the empty directories under the parent directory?

#!/bin/bash

HOST='<hostname>'
USER='<username>'
DIR='<destination directory>'
SOURCE='/srv/torrents/'

rsync -e "ssh -l $USER" --remove-source-files -h -4 -r --stats -m --progress -i $SOURCE $HOST:$DIR
find $SOURCE -mindepth 1 -type d -empty -prune -exec rmdir -p \{\} \;

2 Answers 2

1

You can make use of the fact that rmdir won't remove a non-empty directory:

rmdir {,.}?*/ 2>/dev/null

or, if your version of rmdir has the option:

rmdir --ignore-fail-on-non-empty {,.}?*/

The weird looking glob expands to include regular directories and hidden directories, but exclude . and ...

You don't have to use find unless you need to get at directories below the current level.

Edit:

Try:

find -type d -empty -delete

That does a depth-first search and deletes all empty nested directories.

5
  • @Dennis: But this won't remove empty directories under the current level (e.g. if ./foo/bar/baz/ are all empty folders, it won't remove them.) I need something that will get at directories below the current level, hence why I'm using find.
    – squircle
    Apr 22, 2010 at 15:47
  • @thepurplepixel: See my edit. Apr 22, 2010 at 16:11
  • Just like to point out for any future people reading this question that the edited command requires the -mindepth 1 parameter as well so it doesn't delete the parent directory.
    – squircle
    Apr 30, 2010 at 0:08
  • @thepurplepixel: That's probably safer, but I just tested it and it didn't delete the parent (current) directory. mkdir test; cd test; mkdir sub; find -type d -empty -print -delete; cd ..; ls -ld test; ls -lR test. Still there ("sub" is gone). The directory "test" is not empty until after its contents are deleted (depth-first). Now do cd test; find -type d -empty -print -delete; cd ..; ls -ld test; ls -lR test (re-run it when "test" is already empty). Still there. Apr 30, 2010 at 0:37
  • @Dennis: It may be different for me because I am specifying a certain directory for find to run on (find $DIR -mindepth 1 -type d -empty -delete)... who knows? It seems to work for me, and that's what counts! :)
    – squircle
    Apr 30, 2010 at 0:50
0

you can also do

find $SOURCE -mindepth 1 -type d -empty -prune -print0 | xargs -0 rm -rf
1
  • @MrShunz: Unfortunately, this doesn't seem to work either. It has the same effect as Dennis Williamson's answer. Even if you run it two or three times, it only seems to go two directories deep at most. Thanks, though.
    – squircle
    Apr 22, 2010 at 15:51

You must log in to answer this question.

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