Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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?

share|improve this question

3 Answers 3

up vote 1 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 ...

share|improve this answer
    
didn't think of that! good idea :) –  warren Sep 28 '10 at 13:25
3  
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

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)
share|improve this answer

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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