Будет ли rm -rf * удалять все файлы / папки в текущем каталоге?


20

Будут ли rm -rf *удалены все файлы / папки в текущем каталоге? Я хочу убедиться, что подстановочный знак *не будет перемещаться вверх в верхних каталогах и стереть всю мою файловую систему. : D

Я помню, как делал chmod 777 .* -Rсо chmodскрытыми файлами, и это chmodотредактировало всю мою файловую систему. Очевидно, я был в учетной записи root.


1
Вот почему я бы сделал rm -rf ./*и явно указал текущий каталог ... но Анкур, кажется, говорит, что это все равно не имеет значения.
mpen

@Mark: в чем разница между .. и ./ ..? Вы можете попробовать cd ./ .. и посмотреть, где вы в конечном итоге :)
Йохан

@Johan: Без разницы ... Думаю, в моей сумасшедшей голове больше смысла: D
mpen

@Mark: легкая ошибка :)
Йохан

Ответы:


15

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

rm -rf .file .dir

или используйте правильные образцы шара (спасибо Крис)

rm -rf .[^.]* ..?*

РЕДАКТИРОВАТЬ Суть в том, что вы не можете использовать .*для сопоставления файлов, как .file, потому что .*или .*?будет также соответствовать ..или .. .[^.]*соответствует файлам, как .file, в то время как ..?*соответствует файлам, как ..foo( *соответствует нулю или более символов, в то время как ?соответствует ровно одному).


1
Вам также нужно что-то вроде ..?*перехвата записей, начинающихся с «..» (например ..foo).
Крис Джонсен

@Chris: ОК, я начал это придирчивое безумие, вы правы;)
Бенджамин Банье

речь идет не только о «правильных» шаблонах глобуса, но и о количестве подходящих элементов. в каталогах с огромным количеством файлов оболочка, скорее всего, не сможет дать 50 тыс. файлов за один ход rm. Итак, удаление содержимого каталога с помощью * не самый разумный способ, imho.
Акира

Я думаю, что объяснение xargsнемного выходит за рамки этого вопроса. Например, можно начать думать об этом, когда оболочка жалуется на длину списка аргументов.
Бенджамин Банье

1
я думаю, что это не выходит за рамки, потому что я думаю, что OP не уверен, как достичь его окончательной проблемы / решения: удалить все содержимое каталога. OP просто делает общую «неправильную» вещь, имея в виду уже решение (плохое) и спрашивая, почему это решение вызывает проблемы. лучшим подходом было бы: «как удалить все файлы в каталоге, не удаляя сам каталог?» Решение ОП вызовет проблемы из-за самой природы того, как работает глобализация.
Акира

12

Если вы хотите удалить каталог и все его содержимое, вы можете зайти в chdirродительский каталог и указать им rm -rfэтот каталог по имени, минуя весь вопрос. Если вы хотите удалить содержимое, но сохранить каталог, проще всего удалить все, а затем заново создать каталог.

Сложно придумать глобус, который будет соответствовать всем возможным сохранениям каталога. и ..; легко придумать простой ответ (например, * .??*), который на практике будет работать почти всегда. Это нормально для интерактивного использования, так как его легко запомнить, а время, когда оно не работает, можно определить с помощью post-rm ls -a. Для сценария проще сделать удаление всех и воссоздать пустой каталог.


1
Вот что я бы посоветовал: выбросить каталог и все готово
akira

Даже если это не ответ, это хорошая идея.
Йохан

10

Так как я думаю, что этот вопрос больше о том, что делает * (а не rm), давайте попробуем другой подход.


Если вы не уверены, что делает *, вы можете сначала «протестировать» его, используя безвредную команду, такую ​​как echo. Прежде чем запустить это, попытайтесь угадать, что они покажут, если вы запустите их в своем домашнем каталоге.

echo *
echo .*

Но сначала давайте создадим игровую площадку, чтобы мы могли поиграть со звездами и посмотреть, чем мы закончим.

mkdir ~/star_test/
cd ~/star_test/
>.file1
>file2

Теперь в этом каталоге мы имеем это:

cj@zap:~/star_test$ ls -1a
.
..
.file1
file2

Теперь обратите внимание, что * расширяется в использовании команды echo:

cj@zap:~/star_test$ echo *
file2
cj@zap:~/star_test$ echo .*
. .. .file1

Итак, давайте посмотрим, что происходит с командой rm

cj@zap:~/star_test$ rm -rf *
cj@zap:~/star_test$ ls -1a
.
..
.file1

Как вы видите, он только удалил файл2, так как * расширился только до файла2. Если вы наберете rm -rf. *, Это будет то же самое, что и запись

rm -rf . .. .file1

И, честно говоря, это не выглядит весело;)

Надеюсь, что это проясняет * часть вашего вопроса.


Обновление: Тем не менее, как указывает Анкур Гоэль, в rm встроена какая-то защита (довольно необычная для команд оболочки :)

Давайте создадим новую игровую площадку:

cd ~/star_test/
mkdir -p test1/test2/test3
sudo chown root.root test1
cd test1/test2/test3/
>.file1
>file2

Итак, теперь у нас это снова, но с test1, принадлежащим root в качестве защиты, если rm начнет сходить с ума.

cj@zap:~/star_test/test1/test2/test3$ ls -a
.  ..  file2  .file1
cj@zap:~/star_test/test1/test2/test3$ echo .*
. .. .file1

Итак, давайте удалим все:

cj@zap:~/star_test/test1/test2/test3$ rm -rf .*
rm: cannot remove directory `.'
rm: cannot remove directory `..'
cj@zap:~/star_test/test1/test2/test3$ ls -a
.  ..  file2

И похоже рм не убрал. и .. даже если бы мы сказали ему !!!

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

rm -rf * .*

Но я бы использовал это с осторожностью, так как я не уверен, что все реализации rm ведут себя так!


7

Да. Команда rm -rf удаляет только файлы и папки в текущем каталоге и не поднимается вверх по дереву файлов. rm также не будет следовать символическим ссылкам и удалять файлы, на которые они указывают, поэтому вы не можете случайно удалить другие части вашей файловой системы.


1

Если вы не хотите , чтобы переместить на один уровень вверх , как mpez0 сказал и rm -rfэта папка конкретно, есть способ работы на всех каталогов / файлов , за исключением .и ..в текущей папке, выполнив:

rm -rf $(ls -A)

Конечно, если какой-либо из каталогов / файлов содержит один из символов в IFSспециальной переменной оболочки (например, пробел, табуляция, символ новой строки), вы можете сначала изменить IFS, выполнить команду, а затем восстановить IFS.


0

Гораздо более простой способ очистить всю папку, также избегая проблем «слишком много аргументов», обсуждаемых в этом ответе , состоит в простом удалении и воссоздании самого каталога. Чтобы убедиться, что это работает правильно, когда вы находитесь в каталоге с символическими ссылками, используйте следующие строки:

cd ..
rm -rf $(readlink -f yourdir) #remove the directory, treat the case of a symlink
                        # by using readlink, to recreate the linked-to directory
mkdir $(readlink -f yourdir) # recreate the directory to have it empty
cd yourdir

(Если вы используете yourdirвместо того $(readlink -f yourdir), чтобы заменить ссылку, только если исходное местоположение остается заполненным)


1
Это может сломать вещи, полагаясь на inode папки, и отбросить разрешения, atime / mtime / ctime / btime, расширенные атрибуты и списки контроля доступа.
Даниэль Бек

@DanielBeck спасибо, хорошие моменты. Хотя мне интересно, что будет действительно полагаться на индекс, кроме жестких ссылок (на каталоги, которые в любом случае настоятельно не рекомендуются)? Но разрешения и т.д. важны. Так что в самом общем случае, вероятно, следует использовать xargs...
Тобиас Кинцлер

OS X содержит механизм, который может обрабатывать файлы и папки, которые перемещаются, и при этом сохранять связь. Наиболее заметно в меню « Открыть последние документы» . AFAICT, он использует inode для внутреннего выполнения. Более подробная информация . Я не удивлюсь, если другие системы реализуют нечто подобное, например, в API для программ с графическим интерфейсом.
Даниэль Бек
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.