Коротко: удаление файла в Linux выполняет команда rm file.txt. Чтобы удалить папку со всем содержимым, выполните rm -r dirname; rmdir dirname удаляет только пустую папку. Корзины нет: ничто в оболочке не отменит rm, поэтому сначала выведите список того, что собираетесь удалить.
rm old.log # удалить файл
rm -r project/ # удалить папку со всем содержимым
rm -rf build/ # то же самое, без единого вопроса
rmdir empty-folder/ # удалить папку, только если она пустаяВывод команд на этой странице получен в Debian 12 с GNU coreutils 9.1, findutils 4.9.0, bash 5.2.15 и lsof 4.95 в тестовом каталоге 21 октября 2026 года, частично от имени непривилегированного пользователя; русские сообщения там же, с локалью ru_RU.UTF-8. Части про --preserve-root, chattr, точки монтирования и trash-cli написаны по документации coreutils, e2fsprogs и trash-cli. В Ubuntu, Rocky Linux и AlmaLinux тот же GNU rm. Папка и каталог в Linux — одно и то же; сам rm в своих сообщениях говорит «каталог».
Шпаргалка по rm
| Задача | Команда |
|---|---|
| Удалить файл | rm file.txt |
| Удалить несколько файлов | rm a.log b.log c.log |
| Удалить по шаблону | rm *.tmp |
| Удалить папку со всем содержимым | rm -r dirname |
| То же, без вопросов и без ошибки, если папки нет | rm -rf dirname |
| Удалить пустую папку | rmdir dirname |
| Удалить пустые папки по всему пути | rmdir -p a/b/c |
| Подтверждать каждый файл | rm -i *.conf |
| Один вопрос на большое удаление | rm -I *.log |
| Показывать каждое удаление | rm -rv dirname |
| Файл, имя которого начинается с дефиса | rm -- -file |
| Файл с пробелами в имени | rm "my file.txt" |
| Файлы старше 14 дней | find /path -name '*.log' -mtime +14 -delete |
| Очистить папку, включая скрытые файлы | find dir -mindepth 1 -delete |
Как удалить файл в Linux
rm принимает одно или несколько имён файлов и удаляет их без вопросов и без сообщений. -v печатает каждое удалённое имя. Несуществующее имя считается ошибкой, если не добавить -f: с ним и этот случай тихо завершается успехом.
$ rm -v old.log
removed 'old.log'
$ rm nofile
rm: cannot remove 'nofile': No such file or directory
$ rm -f nofile; echo $?
0С русской локалью те же сообщения переведены, а имена файлов rm и там берёт в обычные апострофы. Причины и решения от языка не зависят:
$ rm -v old.log
удалён 'old.log'
$ rm nofile
rm: невозможно удалить 'nofile': Нет такого файла или каталогаДля удаления файла нужно право на запись в каталог, где он лежит, а не в сам файл. Защищённый от записи файл в вашем собственном каталоге удалить можно, но если rm запущен в терминале, он сначала спросит:
rm: remove write-protected regular empty file 'wp'? nПользователя root rm об этом никогда не спрашивает, а -f отключает вопрос для всех. Имена с пробелами берите в кавычки: rm my file.txt попытается удалить my и file.txt и дважды выдаст No such file or directory, а rm "my file.txt" удалит один нужный файл.
Как удалить папку со всем содержимым
Обычный rm папку удалять отказывается. -r (рекурсивно) удаляет папку, все файлы и все подпапки в ней:
$ rm project
rm: cannot remove 'project': Is a directory
$ rm -rv project
removed 'project/src/main.c'
removed directory 'project/src'
removed directory 'project'rm -rf добавляет -f: никаких вопросов о защищённых от записи файлах и никакой ошибки для несуществующих имён. Поэтому в скриптах это обычная форма, а в командной строке опасная: опечатка в пути выполнится так же тихо. Для пустой папки безопаснее rmdir: каталог, в котором хоть что-то есть, она не удалит:
$ rmdir d
rmdir: failed to remove 'd': Directory not empty
$ rmdir -pv d/e
rmdir: removing directory, 'd/e'
rmdir: removing directory, 'd'В русской локали это rm: невозможно удалить 'project': Это каталог и rmdir: не удалось удалить 'd': Каталог не пуст.
| rm -r | rmdir | rm -d | |
|---|---|---|---|
| Удаляет содержимое | Да, всё внутри | Нет | Нет |
| Папка должна быть пустой | Нет | Да | Да |
| Удаляет и родительские папки | Нет | С -p, пока они становятся пустыми | Нет |
| Подходит для | Удаления дерева целиком | Уборки после скрипта; безопасной проверки, что ничего не осталось | Удаления пустой папки той же командой rm |
rmdir -p d/e удалила d/e, а затем d, потому что d стала пустой, когда не стало e; на первом же родителе, где ещё что-то есть, она останавливается.
Вопросы перед удалением: -i, -I и -f
$ rm -i a
rm: remove regular empty file 'a'? n
$ rm -I c1 c2 c3 c4
rm: remove 4 arguments? n
$ rm -rI tree
rm: remove 1 argument recursively? n-i спрашивает про каждый файл: для трёх файлов это нормально, для трёх тысяч бесполезно. -I спрашивает один раз и только тогда, когда вы удаляете больше трёх файлов или удаляете рекурсивно; с тремя именами или меньше просто выполняется. Поэтому alias rm='rm -I' в ~/.bashrc — разумная страховка, которая не мешает работать. Из -i, -I и -f действует последний в командной строке: rm -f -i спросил, rm -i -f не спросил, так что rm -rf, набранный при таком алиасе, всё равно выполнится без вопроса. Скрипты алиас вообще не видят: bash не раскрывает алиасы в неинтерактивной оболочке.
Имена с дефисом и ловушка rm *
Файл, имя которого начинается с дефиса, выглядит как ключ. GNU rm сам подсказывает, как от него избавиться:
$ rm -foo
rm: invalid option -- 'o'
Try 'rm ./-foo' to remove the file '-foo'.
Try 'rm --help' for more information.
$ rm -- -fooВ русской локали подсказка звучит так: Попробуйте «rm ./-foo», чтобы удалить файл '-foo'. -- завершает список ключей, и всё после него считается именами файлов; ./-foo тоже работает. Тот же механизм делает опасным голый rm *. Оболочка раскрывает * ещё до запуска rm, а GNU rm считает файл с именем -r ключом, где бы он ни оказался в списке:
$ ls
-r a sub
$ echo rm *
rm -r a sub
$ rm * # удаляет sub/ со всем содержимым, хотя -r вы не набиралиПишите rm ./* или rm -- *, и странный файл снова станет просто файлом. Ещё два сюрприза с шаблонами: * не захватывает скрытые файлы, поэтому rm -rf cache/* оставил на месте cache/.hidden, а если совпадений нет вовсе, bash передаёт шаблон как есть, и всё заканчивается сообщением cannot remove '*.tmp': No such file or directory. Чтобы полностью очистить папку, но оставить её саму, используйте find cache -mindepth 1 -delete.
rm -rf / и --preserve-root
GNU rm отказывается рекурсивно работать с самим /. Согласно руководству coreutils, --preserve-root включён по умолчанию, и rm -rf / останавливается с сообщением it is dangerous to operate recursively on '/', если не добавить --no-preserve-root. Полагаться на это не стоит:
rm -rf /*не защищён. Оболочка раскрывает его в/bin /boot /etc ..., и ни один из этих путей не равен/.- Пустая переменная превращается в путь.
rm -rf "$DIR"/*при незаданнойDIR— этоrm -rf /*. Пишитеrm -rf "${DIR:?}"/*: тогда bash остановится с ошибкойDIR: parameter null or not set(по-русскиDIR: параметр не задан или пустой) ещё до запуска rm. - Ошибка в каталоге так же необратима.
rm -rf /var/wwwвместо/var/www/oldничем не защищён.
--preserve-root=all идёт на шаг дальше: тогда rm отказывается и от любого аргумента, который лежит на другой файловой системе, чем его родительский каталог, например от смонтированного диска с бэкапами.
Удаление по возрасту или шаблону: find -delete
Если нужно что-то избирательнее шаблона, пусть файлы подбирает find: сначала запустите его с -print и только потом замените -print на -delete:
$ find logs -name '*.log' -mtime +14 -print
logs/a.log
logs/old/b.log
$ find logs -name '*.log' -mtime +14 -delete
$ find logs -type d -empty -delete # затем папки, которые стали пустымиПривычки, которые уберегут от беды
- 1Выведите список того, что заденет команда
Запустите тот же путь с
ls -d, тот же find с-printили поставьтеechoперед rm. Прочитайте список, затем нажмите стрелку вверх и поменяйте только саму команду. - 2В скриптах используйте абсолютные пути
С относительным путём rm удаляет файлы в том каталоге, где скрипт оказался запущен. Задания cron стартуют в домашнем каталоге пользователя, а не там, где лежит скрипт.
- 3Защищайте переменные
"${VAR:?}"для каждой переменной, из которой складывается путь для rm, плюсset -uв начале скрипта. - 4Где уместно, перемещайте в корзину
Пакет trash-cli (в Debian и Ubuntu:
apt install trash-cli) добавляетtrash-put,trash-list,trash-restoreиtrash-empty, которые пользуются той же папкой корзины, что и графические файловые менеджеры. Удобно в интерактивной работе; на сервере место освобождается только после очистки корзины.
Можно ли отменить rm?
Нет. rm убирает имя из каталога, а файловая система помечает блоки как свободные; корзины и отмены нет. Программы восстановления для ext4 иногда находят блоки, которые ещё ничем не перезаписаны, но сервер, который продолжает писать логи и кеши, с каждой минутой уменьшает эти шансы. Что действительно работает:
- Бэкап или снапшот, сделанный раньше. На VPS VMHeaven снапшоты создаются в личном кабинете, вручную или по расписанию (ежедневно, еженедельно или ежемесячно), и там же восстанавливаются. Снапшот прямо перед чисткой обходится в минуту времени.
- Процесс, у которого файл всё ещё открыт. Пока он не закроет файл, данные остаются на диске и читаются через
/proc. В тесте удалённый файл, открытый процессом, вернулся целиком командойcp /proc/PID/fd/3 data.db.recovered.sudo lsof +L1показывает PID и номер дескриптора.
Ошибки rm и что они значат
| Сообщение заканчивается на | Что значит | Как исправить |
|---|---|---|
| Is a directory (Это каталог) | rm без -r на папке | rm -r |
| Directory not empty (Каталог не пуст) | rmdir или rm -d на папке с содержимым; при rm -rf в неё продолжал что-то писать другой процесс | rm -r, или сначала остановите того, кто пишет |
| No such file or directory (Нет такого файла или каталога) | Опечатка, пробелы без кавычек или шаблон, который ничего не нашёл | Проверьте через ls; возьмите имя в кавычки |
| Permission denied (Отказано в доступе) | Нет права на запись в каталог, где лежит файл | См. ниже |
| Operation not permitted (Операция не позволена) | Атрибут immutable или append-only либо sticky-бит (/tmp) | lsattr, затем chattr -i (или -a); в /tmp удаляет только владелец файла или root |
| Device or resource busy (Устройство или ресурс занято) | Путь является точкой монтирования или содержит её ниже | findmnt, затем umount |
| Read-only file system (Файловая система доступна только для чтения) | Файловая система смонтирована только для чтения | Read-only file system (англ.) |
| invalid option (неверный ключ) | Имя файла начинается с дефиса | rm -- -name |
rm: cannot remove: Permission denied (Отказано в доступе)
rm: cannot remove 'f': Permission denied
rm: cannot remove 'locked/f': Permission deniedОба файла были доступны на запись только root, но причина не в этом: каталоги, в которых они лежали, принадлежали root, а удаление имени меняет именно каталог. В каталоге со sticky-битом, как /tmp, можно удалять только свои файлы, даже при праве на запись в сам каталог; в этом случае rm сообщает Operation not permitted. Проверьте родительский каталог командой ls -ld и исправьте владельца или права, как описано в статье о chmod (англ.), или выполните rm через sudo, если файлы действительно принадлежат системе.
rm: cannot remove: Operation not permitted, даже у root
Если root получает Operation not permitted, у файла обычно стоит атрибут immutable. Согласно man-странице chattr, файл с +i никто не может удалить, переименовать, изменить или создать на него жёсткую ссылку, пока атрибут не снят:
lsattr suspicious.conf # 'i' среди флагов означает immutable
sudo chattr -i suspicious.conf
sudo rm suspicious.confЕсли атрибут immutable ставили не вы, присмотритесь к файлу перед удалением: злоумышленники используют chattr +i, чтобы удержать на месте подброшенную запись cron или SSH-ключ.
rm: cannot remove: Device or resource busy
Точку монтирования нельзя удалить, пока на ней смонтирована файловая система. На это натыкается rm -r на папке, внутри которой что-то смонтировано, например том Docker или bind-монтирование. findmnt -R /path покажет, что там смонтировано. Обратите внимание, что происходит до ошибки: по умолчанию rm заходит в смонтированные файловые системы и удаляет внутри всё, что может, и только потом спотыкается о точку монтирования. Сначала отмонтируйте или добавьте --one-file-system: с ним rm пропускает каждый каталог, который лежит на другой файловой системе, чем указанный вами путь. На NFS то же сообщение могут вызывать файлы .nfsXXXX: они заменяют удалённые файлы, которые процесс всё ещё держит открытыми, и исчезают, когда процесс их закрывает.
Удалили большой файл, а диск всё ещё заполнен?
Удаление убирает имя. Если процесс всё ещё держит файл открытым (обычно это лог, в который продолжает писать приложение), место остаётся занятым, пока процесс его не закроет. df говорит, что диск полон, а du ничего не находит. lsof +L1 показывает файлы, у которых не осталось имени:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
sleep 353107 root 3w REG 8,1 5242880 0 3542659 /srv/app/app.log (deleted)Чтобы освободить место, перезапустите процесс или попросите его заново открыть логи, а лог, который больше не нужен, можно обнулить через /proc командой : > /proc/353107/fd/3: в тесте SIZE/OFF упал до 0, а процесс продолжил работать. Как отсортировать этот список на нагруженном сервере, показано в статье о lsof (англ.), а остальные причины переполненного диска разобраны в статье No space left on device. Прежде чем что-то удалять ради места, посмотрите, что его на самом деле занимает, с помощью du и df (англ.).
Частые вопросы
Как удалить папку со всем содержимым в Linux?
Выполните rm -r имя_папки: команда удалит папку вместе со всеми файлами и подпапками. rm -rf делает то же без вопросов и без ошибки, если такого имени нет. Перед удалением проверьте путь через ls -d: корзины и отмены в rm нет.
Чем rm -r отличается от rmdir?
rmdir удаляет только пустые папки и в остальных случаях завершается ошибкой Directory not empty (в русской локали «Каталог не пуст»), поэтому годится как безопасный шаг уборки. rm -r удаляет папку вместе со всем содержимым. rmdir -p удаляет ещё и родительские папки, которые стали пустыми.
Можно ли восстановить файл, удалённый через rm?
Средствами оболочки нет: у rm нет корзины и отмены, поэтому восстанавливайте файл из бэкапа или снапшота. Исключение одно: пока работающий процесс держит файл открытым, его данные можно скопировать из /proc/PID/fd/НОМЕР. sudo lsof +L1 покажет PID и номер дескриптора.