Können bei der Ausführung von `rm -rf 'bestimmte Unterverzeichnisse ausgeschlossen werden?

13772
warren

Ich verwende regelmäßig Bind-Mounts, um den Speicherplatz an mehreren Orten verfügbar zu machen, ohne dass mehrere logische Volumes / physische Partitionen / LUNs usw. erforderlich sind.

Zum Beispiel kann ich eine 200G LV an haben /space. Von dort aus werde ich Unterverzeichnisse wie var_optund var_logdie machen, die ich dann an /var/optund binden kann /var/log.

Kann ich bei einer Bereinigung des 'space' -Verzeichnisses Verzeichnisse von einem rm -rflaufenden Verzeichnis ausschließen/space ?

Beispiel:

# pwd /space # rm -rf *  

Gibt es einen anderen oder besseren (aber ähnlich einfachen) Weg, um das zu erreichen, was ich versuche, an das ich nicht gedacht habe?

4

4 Antworten auf die Frage

11
Gilles

Einfach konzeptionell und mit geringem Fehlerrisiko:

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

Sie können auch die erweiterten Globs von ksh verwenden:

rm -rf !(var_opt|var_log) 

Diese sind auch in bash verfügbar, wenn Sie sie aktivieren:

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

Dito in zsh:

setopt ksh_glob rm -rf !(var_opt|var_log) 

Zsh hat auch seine eigenen erweiterten Globs:

setopt extended_glob rm -rf ^var_(opt|log) 
2
Ole Tange

Wenn Ihre Eingabedateinamen von Benutzern generiert werden, müssen Sie mit überraschenden Dateinamen arbeiten, die Leerzeichen, 'oder' im Dateinamen enthalten.

Die Verwendung von xargskann aufgrund des Separatorproblems zu bösen Überraschungen führen .

GNU Parallel hat dieses Problem nicht.

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

Sehen Sie sich das Intro-Video für GNU Parallel an, um mehr zu erfahren.

1
Janne Pikkarainen

Vielleicht mit find + xargs + rm Kombination?

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

oder etwas in dieser Melodie. Natürlich kann es sinnvoll sein, dass xargs zuerst etwas harmloseres Echo ausführt, bevor es in rm geändert wird.

habe nicht daran gedacht! gute Idee :) warren vor 13 Jahren 0
** Verwenden Sie keine xargs ** (außer bei "-0")! Es erwartet, dass die Eingaben auf eine sehr eigenartige Weise zitiert werden, die `find` nicht generiert. Dieser Befehl schlägt daher fürchterlich fehl, wenn Dateinamen Leerzeichen oder "\" enthalten. Verwenden Sie stattdessen "-exec": find / space! -Iregex (var_opt | var_log) '-exec rm {} + ` Da `-iregex` ohnehin spezifisch für GNU find ist, verwenden Sie die` -delete`-Aktion: `find / space! -iregex '(var_opt | var_log)' -delete`. Gilles vor 13 Jahren 4
1
Toby Speight

If the directories you want to preserve are exactly the mountpoints, you might be able to use --one-file-system in GNU rm.

I haven't investigated how this is implemented, but I'm guessing that this won't do what you want if the bind mount is from within the same filesystem, so be careful! rm doesn't have a --no-act option, but you can pipe yes no | rm -ir . for example.