← Весь справочник

rm

Удаление файлов и каталогов — без корзины и без возврата

rm удаляет имена файлов. Корзины нет: удалённое не восстановить. Данные освобождаются, когда исчезает последнее имя (жёсткая ссылка) и файл никем не открыт. Для пустых каталогов есть rmdir. В песочнице — GNU coreutils 9.4.

Синтаксис

rm [опции] файл…
rm -r [опции] каталог…
rmdir [опции] пустой_каталог…

Код возврата: 0 — всё удалено, 1 — что-то не получилось (нет файла, нет прав, каталог без -r).

Опции rm

ОпцияЧто делает
-r, -Rудалять каталоги вместе со всем содержимым
-dудалять пустые каталоги (как rmdir)
-fне спрашивать и не ругаться на несуществующие файлы; код возврата 0
-iспрашивать про каждый файл
-Iспросить один раз, если файлов больше трёх или есть -r; мягкая страховка от rm *
--interactive=never|once|alwaysто же длинно: never ≈ без вопросов, once = -I, always = -i
-vпечатать каждое удаление: removed 'd/f', removed directory 'd'
--one-file-systemпри -r не заходить в другие смонтированные ФС
--preserve-rootотказаться удалять / (включено по умолчанию)
--конец опций: всё дальше — имена файлов

Из -f, -i, -I действует последняя указанная.

Опции rmdir

ОпцияЧто делает
-pудалить каталог и затем его пустых родителей: rmdir -p a/b/c удалит c, b, a
-vпечатать каждое удаление
--ignore-fail-on-non-emptyмолча пропускать непустые каталоги

rmdir удаляет только пустые каталоги — это и есть его плюс: случайно снести данные им нельзя.

Когда rm спрашивает сам

Без -i rm задаёт вопрос remove write-protected regular file?, только если:

  • у файла нет права записи для тебя (root на такие вопросы не нарывается — ему писать можно всегда),
  • и стандартный ввод — терминал. В скрипте и в конвейере вопроса нет, файл удаляется.

Права на сам файл для удаления не важны: нужны права записи и входа (w и x) на каталог, в котором он лежит. В каталоге со sticky-битом (/tmp) чужие файлы удалить нельзя.

Примеры

# удалить файл
rm old.log

# каталог со всем содержимым, с отчётом
rm -rv build/

# без ошибки, если файла нет (удобно в скриптах)
rm -f /tmp/app.lock

# один вопрос перед массовым удалением
rm -I *.tmp

# удалить файл с именем, начинающимся с дефиса
rm -- -file.txt
rm ./-file.txt

# пустой каталог и пустых родителей
rmdir -p cache/2024/01

# все .bak в дереве — безопасно для имён с пробелами
find . -name '*.bak' -type f -delete
find . -name '*.bak' -print0 | xargs -0 rm -f --

# сначала посмотри, что попадёт под шаблон
echo rm -r /srv/app/releases/old-*

Подводные камни

  • Корзины нет. Перед rm -rf с переменной или шаблоном сначала выполни то же с echo или ls.
  • Пустая переменная. rm -rf "$DIR/"* при пустом $DIR превращается в rm -rf /*. Защита: rm -rf "${DIR:?не задан}"/* — при пустой переменной оболочка остановится с ошибкой.
  • Имя с дефиса: rm -x → «invalid option -- 'x'». Пиши rm -- -x или rm ./-x.
  • rm -f скрывает опечатки: несуществующий путь не даст ни ошибки, ни ненулевого кода возврата.
  • Пробел в пути: rm -rf /srv/app /old удалит два каталога — /srv/app и /old. Пути с переменными бери в кавычки.
  • Место не освобождается, если файл держит открытым процесс: имя исчезло, данные остаются до закрытия. Такие файлы видно в /proc/*/fd как (deleted). Для живых логов вместо rm используй truncate -s 0.
  • rm -rf / без --no-preserve-root откажется работать, а вот rm -rf /* — нет: шаблон раскроет оболочка.
  • rm -r . и rm -r .. запрещены: «refusing to remove '.' or '..' directory».

См. также

find · mv · ln · truncate · chmod · mkdir · proc