Очистка текущей директории rm -r * в unix

4

Это правильный способ очистки текущего каталога, верно?

rm -r * .

источник

Ответы:

5

Обычно я просто перемещаюсь на один уровень вверх по иерархии, затем удаляю каталог по имени и воссоздаю его:

cd ..
rm -rf dirname
mkdir dirname
cd dirname

потому что это устраняет ошибку в случае использования rm -rf * в неправильном каталоге.

Замечания: Если каталог имеет нестандартные разрешения или принадлежит какой-либо другой учетной записи, вы потеряете его при удалении и повторном создании каталога. Это не то, что возникает у меня очень часто, но стоит задуматься.

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

Mark Bessey
источник
+1 Это также исключает возможность переполнения аргументов командной строки. IIRC, вы можете иметь только 1 КБ для аргументов cmd, поэтому rm * может расшириться до большего. Воссоздание директории ИМХО - лучший вариант (если у вас нет жестких ссылок, но это просто грязно).
beatgammit
Я не уверен, что такой подход гарантирует, что dirname будет создан с теми же правами / владельцем, которые были у него до того, как вы его удалили, может быть хорошей идеей проверить это перед удалением.
AnonymousLurker
@AnonymousLurker, я упомянул проблему с разрешениями. Для меня это решение на 90% - у меня редко бывают каталоги с нечетными разрешениями (по крайней мере, по сравнению с количеством каталогов со странными именами файлов).
Mark Bessey
1
@MarkBessey Я предлагаю вам добавить более ясное слово (в отношении разрешений для каталога) в ваш ответ.
guntbert
6

Нет, и по нескольким причинам: 1) эта команда попытается удалить ., который является текущим каталогом, и, таким образом, потерпит неудачу; 2) эта команда не удалит «скрытые» файлы, начинающиеся с символа «.» персонаж; 3) команда не удалит каталоги.

Вы могли бы использовать rm -rf *, Это удалит все файлы и каталоги, но не удалит точечные файлы. Вы могли бы использовать find . -type f | xargs rm удалить все файлы, включая скрытые, но это не приведет к удалению каталогов.

Итак, вы можете использовать это:

$ find . -print0 -type f -o -type d -not -name '\.' | xargs -0 rm -rf

Здесь вы рекурсивно находите все файлы и каталоги (если они не называются «.»), А затем удаляете их. -print0 а также -0 аргументы позволяют ему правильно обрабатывать имена файлов с пробелами в их именах.


источник
2
Этот код не удаляет все элементы. Просто подумайте о предмете с пробелом в его названии. Так лучше использовать -print0 с find а также -0 с xargs,
Shi
Вы правы, спасибо. Я редактировал это.
Unix сильно отличается от Linux? я могу использовать rm --recursive * .*[^.]* на Linux, и было интересно, будет ли это работать на Unix.
Paddy Landau
1
@PaddyLandau Это не комментарий к этому ответу, на самом деле; это отдельный вопрос. И «Unix» - это очень широкий термин, охватывающий все, от HP-UX и AIX до Mac OS X. Тем не менее, мне кажется, это так rm Команда удалит все не-точечные файлы и все точечные файлы, которые содержат хотя бы один не-точечный символ. Пытаться touch ... (да, три периода), затем запустить его.
a CVn
@ MichaelKjörling - спасибо, но я предлагал это в качестве альтернативы. Я не был уверен, будет ли это работать в Unix (я использую Linux), поэтому я разместил комментарий, а не отдельный ответ. Если это работает в Linux, я бы посчитал это простым ответом. КСТАТИ, touch ... действительно создает скрытый файл с именем ... в линуксе
Paddy Landau
2

Вы можете сделать это, если доступны ключи -mindepth и -delete:

find . -mindepth 1 -delete

Если вы хотите придерживаться POSIX , вы можете сделать это (как видно на unix.com ):

find . \( ! -name . -prune \) -exec rm -rf {} \+
Paulo Almeida
источник
1

Одно простое решение, если вы не хотите использовать find, - это удалить текущий каталог, а затем воссоздать его:

rm -rf "`pwd`" && mkdir "`pwd`" && cd "`pwd`"
vimdude
источник
Вы, вероятно, захотите кешировать pwd, Я не уверен, будет ли это работать правильно после удаления. _dir=$(pwd) ; rm -rf "$_dir" && ..., Хотя не проверял, так что я могу ошибаться.
beatgammit
1

Если вы используете bash (версия 4 или выше), вы можете использовать dotglob опция оболочки, чтобы включить имена файлов, начинающиеся с точки в вашем глобусе.

shopt -s dotglob
rm -r -- *

Вышеприведенное будет разбито на каталоги, содержащие много сотен тысяч файлов; в этом случае вы можете использовать printf (который, будучи встроенным в Bash, смеется в лице ARG_MAX ) а также xargs (который предоставит безопасное количество аргументов rm ).

shopt -s dotglob
printf '%q ' * | xargs rm -r --

Вы можете сбросить dotglob как только вы закончите с:

shopt -u dotglob

Другой способ сделать это без возни с опциями оболочки:

rm -r -- * .[^.]* ..?*
##  or
printf '%q ' * .[^.]* ..?* | xargs rm -r --

Первый шар * будет соответствовать всему в текущем каталоге, который не начинается с точки; второй .[^.]* соответствует всему, что начинается с точки, за которой следует один не точечный символ, за которым следует любое количество других символов; третий шар соответствует двум точкам, за которыми следует любой один символ, за которым следует любое количество других символов. Это может быть полезно, если вы застряли в оболочке без опции dotglob; однако в таком случае printf может не быть встроенной оболочкой или может не иметь %q флаг (который цитирует все пробелы и необычные символы в переданных ему аргументах, делая их безопасными для передачи xargs ), так что вы, вероятно, должны использовать один из find решения в таком случае.

evilsoup
источник
Если у вас огромный список каталогов, это может не сработать из-за количества аргументов CMD.
beatgammit
@tjameson да, хотя это должно быть довольно большое количество файлов ...
evilsoup
Я столкнулся с этим только на прошлой неделе на работе. Это было что-то около 500 000 файлов ...
beatgammit
@tjameson ... хорошо, тогда я отредактирую заявление об отказе от ответственности
evilsoup