При запуске `rm -rf` возможно ли исключить определенные подкаталоги?

13673
warren

Я обычно использую bind mounts, чтобы помочь сделать пространство доступным в нескольких местах без необходимости иметь несколько логических томов / физических разделов / LUN и т. Д.

Например, у меня может быть 200G LV установлен в /space. Оттуда я создам подкаталоги, подобные var_optи var_logкоторые я могу затем привязать к mount /var/optи /var/logсоответственно.

Можно ли при очистке каталога 'space' исключать каталоги из rm -rfвнутренней среды /space?

Пример:

# pwd /space # rm -rf *  

Есть ли другой или лучший (но такой же простой) способ выполнить то, что я пытаюсь сделать, о котором я не думал?

4

4 ответа на вопрос

11
Gilles

Простая концептуально и имеет низкий риск ошибки:

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

Вы также можете использовать расширенные глобусы ksh:

rm -rf !(var_opt|var_log) 

Они также доступны в bash, если вы включите их:

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

То же самое в зш:

setopt ksh_glob rm -rf !(var_opt|var_log) 

У Zsh также есть свои собственные расширенные глобусы:

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

Если ваши имена входных файлов генерируются пользователями, вам нужно иметь дело с неожиданными именами файлов, содержащими пробел, 'или "в имени файла.

Использование xargsможет привести к неприятным сюрпризам из-за проблемы с разделителем .

У GNU Parallel такой проблемы нет.

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

Посмотрите вступительное видео для GNU Parallel, чтобы узнать больше.

1
Janne Pikkarainen

Может быть, с помощью комбинации find + xargs + rm?

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

или что-то в этой мелодии. Конечно, было бы разумно сначала проинструктировать xargs выполнить что-то более безвредное, например, echo, прежде чем изменить его на rm ...

не думал об этом! отличная идея :) warren 13 лет назад 0
** Не используйте xargs ** (кроме как с `-0`)! Он ожидает, что входные данные цитируются весьма своеобразным образом, который `find` не генерирует. Так что эта команда будет ужасно терпеть неудачу, если есть имена файлов, содержащие пробелы или `\ '" `. Вместо этого используйте` -exec`: find / space! -Iregex' (var_opt | var_log) '-exec rm {} + `. Или поскольку `-iregex` специфичен для GNU find в любом случае, используйте действие` -delete`: `find / space! -iregex '(var_opt | var_log)' -delete`. Gilles 13 лет назад 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.