rm — одна из немногих команд Linux где ошибка обходится дорого. Нет корзины, нет подтверждения по умолчанию, нет отмены. Файл исчезает сразу. Поэтому стоит понять как она работает до того как понадобится удалять что-то важное.
Базовое удаление
Удалить файл:
rm file.txt
Удалить несколько файлов сразу:
rm file1.txt file2.txt file3.txt
Удалить по маске — все .log файлы в текущей директории:
rm *.log
Удалить файл в конкретном пути:
rm /var/log/nginx/access.log
Удаление директорий: флаг -r
Без флага -r попытка удалить директорию даст ошибку is a directory. Рекурсивное удаление вместе со всем содержимым:
rm -r /path/to/directory
Удаляет всё: вложенные папки, файлы, симлинки внутри. Без запроса подтверждения.
Не спрашивать вообще: флаг -f
-f (force) подавляет все предупреждения и не выдаёт ошибку если файла не существует:
rm -f file.txt
Комбинация -rf — удалить директорию без каких-либо вопросов:
rm -rf /path/to/directory
Это самая опасная комбинация в Linux. -rf с неправильным путём или опечаткой — необратимая потеря данных. Перед запуском всегда проверять путь.
Спрашивать перед каждым удалением: флаг -i
Противоположность -f — запрашивать подтверждение на каждый файл:
rm -i *.log
rm: remove regular file 'access.log'?
rm: remove regular file 'error.log'?
Для массовых операций неудобно, но спасает от случайных удалений при работе с масками.
Флаг -I (заглавная) — спрашивает один раз если файлов больше трёх или используется рекурсия:
rm -rI /var/log/oldlogs/
Вывести что удаляется: флаг -v
rm -rv /tmp/cache/
removed '/tmp/cache/session1'
removed '/tmp/cache/session2'
removed directory '/tmp/cache/'
Полезно в скриптах где нужна трассировка — видно что именно было удалено.
Не выходить за пределы файловой системы: --one-file-system
При рекурсивном удалении директорий которые содержат точки монтирования — есть риск удалить содержимое смонтированного диска или NFS-шары. Флаг --one-file-system останавливается на границе файловой системы:
rm -rf --one-file-system /mnt/backup/old/
Если внутри /mnt/backup/old/ есть примонтированный раздел — rm его пропустит.
Файлы с необычными именами
Файл начинающийся с дефиса — rm интерпретирует его как флаг и ругается:
rm -- -filename.txt
-- сообщает что дальше идут только аргументы, не флаги.
Файл с пробелами в имени:
rm "my file with spaces.txt"
Файл с непечатаемыми символами в имени — удалить по inode:
ls -i
find . -inum 123456 -delete
Удалить всё кроме одного файла
Удалить все файлы в директории кроме config.conf:
find /path -not -name "config.conf" -type f -delete
Или через расширение bash:
rm !(config.conf)
Для этого нужно включить extglob:
shopt -s extglob
rm !(config.conf)
Безопасная альтернатива: trash-cli
trash-cli — утилита которая отправляет файлы в корзину вместо немедленного удаления. Позволяет восстановить удалённое:
sudo apt install trash-cli
Переместить в корзину:
trash file.txt
Посмотреть что в корзине:
trash-list
Восстановить файл:
restore-trash
Очистить корзину:
trash-empty
Если файл уже удалён: попытка восстановления
rm не перемещает файл — она удаляет запись в директории и помечает inode как свободный. Данные на диске остаются до перезаписи. Чем раньше начать восстановление — тем выше шансы.
Инструмент для восстановления на ext4:
sudo apt install extundelete
sudo extundelete /dev/sda1 --restore-file path/to/file.txt
На продакшн-сервере — сначала размонтировать раздел или перевести в read-only, иначе новые записи затрут удалённые данные.
Шпаргалка
| Задача | Команда |
|---|---|
| Удалить файл | rm file.txt |
| Удалить несколько файлов | rm file1.txt file2.txt |
| Удалить директорию | rm -r /path/dir |
| Без подтверждений | rm -rf /path/dir |
| Спрашивать каждый раз | rm -i *.log |
| Показать что удаляется | rm -rv /path/dir |
| Не выходить за ФС | rm -rf --one-file-system /path/ |
| Файл с дефисом в имени | rm -- -filename.txt |
| Удалить кроме одного | find /path -not -name "keep.txt" -delete |
| В корзину вместо удаления | trash file.txt |