I routinely use bind mounts to aid in making space available in multiple locations without having to have multiple logical volumes / physical partitions / LUNs, etc.

For example, I may have a 200G LV mounted at /space. From there, I will make subdirectories like var_opt and var_log which I can then bind mount to /var/opt and /var/log, respectively.

When doing a cleanup on the 'space' directory, is it possible to exclude directories from an rm -rf running inside /space?

Example:

# pwd
/space
# rm -rf * {except-for-var_opt-and-var_log}

Is there a different or better (but similarly simple) way to accomplish what I'm trying to do that I haven't thought of?

link|improve this question

feedback

3 Answers

up vote 2 down vote accepted

Maybe with find + xargs + rm combination?

find /space ! -iregex '(var_opt|var_log)' | xargs rm -f

or something in that tune. Of course, it might be wise to first instruct xargs execute something more harmless, such as echo, before changing it to rm ...

link|improve this answer
didn't think of that! good idea :) – warren Sep 28 '10 at 13:25
2  
Do not use xargs (except with -0)! It expects input quoted in a highly peculiar way that find does not generate. So this command will fail horribly if there are file names containing spaces or \'". Instead, use -exec: find /space ! -iregex '(var_opt|var_log)' -exec rm {} +. Or since -iregex` is specific to GNU find anyway, use its -delete action: find /space ! -iregex '(var_opt|var_log)' -delete. – Gilles Sep 28 '10 at 23:14
feedback

Simple conceptually, and has a low risk of error:

mkdir TO_DELETE
mv * TO_DELETE
mv TO_DELETE/var_opt TO_DELETE/var_log .
rm -rf TO_DELETE

You can also use ksh's extended globs:

rm -rf !(var_opt|var_log)

These are also available in bash if you enable them:

shopt -s extglob
rm -rf !(var_opt|var_log)

Ditto in zsh:

setopt ksh_glob
rm -rf !(var_opt|var_log)

Zsh also has its own extended globs:

setopt extended_glob
rm -rf ^var_(opt|log)
link|improve this answer
feedback

If your input file names are generated by users, you need to deal with surprising file names containing space, ', or " in the filename.

The use of xargs can lead to nasty surprises because of the separator problem http://en.wikipedia.org/wiki/Xargs#The_separator_problem

GNU Parallel http://www.gnu.org/software/parallel/ does not have that problem.

find /space ! -iregex '(var_opt|var_log)' | parallel -X rm -f

Watch the intro video for GNU Parallel to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

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