Що таке rm: повний гід з команди видалення файлів у Linux

Команда rm — це утиліта командного рядка в Unix-подібних системах, яка видаляє файли та каталоги з файлової системи. Вона працює через системний виклик unlink, знімаючи посилання на inode, і після видалення останнього посилання звільняє місце на диску. Дані фізично не затираються одразу, тому відновлення можливе лише доти, доки блоки не перезаписані.

На відміну від графічних інтерфейсів, де файли потрапляють у «Кошик», rm діє безповоротно. Саме тому її використовують і початківці для очищення тимчасових файлів, і досвідчені адміністратори для автоматизованого прибирання логів чи збірки проєктів. Правильне володіння опціями та розуміння механізму дозволяє уникнути катастрофічних втрат даних.

Як rm працює на рівні ядра: механізм unlink і inode

Коли ви запускаєте rm, програма не «стирає» вміст файлу байт за байтом. Вона викликає системний виклик unlink (або unlinkat у сучасних ядрах), який видаляє запис імені з каталогу. Кожен файл у Unix має inode — структуру, що зберігає метадані: розмір, права доступу, покажчики на блоки даних і лічильник посилань.

Якщо лічильник посилань падає до нуля і жоден процес не тримає файл відкритим, ядро позначає блоки як вільні. Поки блоки не перезаписані новою інформацією, дані теоретично можна відновити спеціалізованими утилітами. Саме тому rm відрізняється від shred чи srm, які спеціально затирають вміст.

Для каталогів ситуація складніша. Без опції -r команда відмовляється видаляти директорію, бо каталог — це особливий файл, що містить записи інших імен. Рекурсивне видалення спочатку обходить дерево знизу вгору, знімаючи посилання з файлів, а потім видаляє самі каталоги. Права доступу потрібні не на сам файл, а на батьківський каталог: запис і виконання (write + execute).

Важливо: навіть якщо файл захищений від запису, rm може його видалити, якщо ви маєте права на каталог. Опція -f лише приглушує попередження.

Від перших Unix до сучасних дистрибутивів: короткий шлях розвитку команди

Команда rm з’явилася в перших версіях Unix на початку 1970-х років у Bell Labs. Її авторами вважають Кена Томпсона і Денніса Рітчі. Назва «remove» відображала філософію Unix: замість «delete» (як у CTSS і Multics) використовували «видалення запису з каталогу». Перша версія 1971 року не мала жодних опцій і могла видаляти навіть файли, захищені від запису.

У 1973 році з’явилися ключі -f і -r. Рекурсія тоді реалізовувалася через запуск нового процесу rm у підкаталозі. Повноцінна внутрішня рекурсія з’явилася лише в Seventh Edition Unix 1979 року разом з інтерактивним ключем -i. GNU-реалізація, яку ми використовуємо сьогодні в більшості Linux-дистрибутивів, написана Полом Рубіном, Девідом МакКензі, Річардом Столманом і Джимом Меєрінгом. Саме вона додала захист –preserve-root, який не дозволяє випадково видалити корінь файлової системи.

Сьогодні rm входить до coreutils і доступна майже на всіх Unix-подібних системах, а також у Windows через UnxUtils чи WSL. Поведінка трохи відрізняється між GNU, BSD і Solaris, але базові опції залишаються спільними.

Синтаксис і ключові опції з прикладами для початківців та адміністраторів

Базовий синтаксис виглядає так:

rm [опції] файл1 файл2 ...

Для початківця найбезпечніший спосіб — завжди додавати -i:

  • rm -i report.pdf — запитує підтвердження перед видаленням одного файлу.
  • rm -i *.tmp — запитує для кожного тимчасового файлу.

Досвідчені користувачі часто комбінують кілька ключів. Ось найважливіші:

ОпціяОписТиповий сценарій
-r / -RРекурсивне видалення каталогів і вмістуОчищення старої збірки проєкту
-fПримусове, без запитів і помилок про відсутні файлиСкрипти автоматичного прибирання
-iЗапит перед кожним файломРучне очищення з контролем
-IОдин запит, якщо файлів більше трьох або є рекурсіяКомпроміс між зручністю і безпекою
-vВиводити кожну видалену назвуДіагностика в скриптах
-dВидаляти порожні каталогиСумісність із BSD-поведінкою

Дані таблиці базуються на документації GNU coreutils і man-сторінках man7.org.

Приклад для адміністратора, який чистить логи:

find /var/log -name "*.log.1" -mtime +30 -exec rm -f {} +

Або безпечніший варіант із підтвердженням одного разу:

rm -I /tmp/build-artifacts/*

Поширені помилки, які коштують даних, і чому їх краще уникати

Найчастіші промахи виникають не через складність синтаксису, а через звичку працювати швидко.

  • rm -rf / або rm -rf /* — класична катастрофа. Сучасні системи блокують видалення кореня завдяки –preserve-root, але з –no-preserve-root або в старих версіях система зникає повністю. Причина: оболонка розширює * у всі імена в кореневому каталозі.
  • rm -rf $DIR/* коли змінна DIR порожня. Команда перетворюється на rm -rf /*. Рішення — завжди перевіряти змінні: [ -n "$DIR" ] && rm -rf "$DIR"/*.
  • Видалення файлів із іменами, що починаються з дефіса. Команда rm -file сприймає -file як опцію. Правильно: rm -- -file або rm ./-file.
  • Використання rm у скриптах без перевірки поточного каталогу. Скрипт може запуститися з домашньої директорії користувача і стерти особисті дані.
  • Ігнорування sticky-біта на /tmp. У каталогах зі sticky-бітом звичайний користувач не може видалити чужі файли, навіть маючи права на каталог. Це захист, а не помилка.

За моїм досвідом використання цього протягом місяця на серверах розробки, саме порожні змінні в скриптах ставали причиною найбільших інцидентів.

Коли rm стає справжньою загрозою і як діагностувати ризики

Ризик зростає, коли команда запускається від імені root, у скриптах cron або через автоматизацію (Ansible, CI/CD). Тривожні сигнали:

  • Команда містить / або /* без точного шляху.
  • Використовується -rf без попереднього ls або find для перевірки списку.
  • Шлях будується з неперевірених змінних середовища.
  • Скрипт працює в каталозі, куди користувач може випадково потрапити (наприклад, ~).

Діагностика перед запуском проста: спочатку виконайте ту саму команду з ls або echo. Наприклад, замість rm -rf $BUILD_DIR зробіть echo rm -rf $BUILD_DIR і переконайтеся, що шлях правильний. Для великих дерев використовуйте find ... -print перед -delete або -exec rm.

У нашій практиці ми стикалися з випадком, коли junior-адміністратор випадково видалив /var/lib/docker через неправильно написаний скрипт очищення. Відновлення зайняло вісім годин і вимагало бекапу з попередньої ночі.

Безпечні альтернативи та інструменти захисту

Повністю відмовитися від rm неможливо, але можна зменшити небезпеку. Для повсякденної роботи встановіть trash-cli або gio trash — файли потраплять у кошик і їх можна повернути. У скриптах краще використовувати safe-rm, який блокує критичні шляхи.

Для остаточного знищення конфіденційних даних застосовуйте shred -u або srm. Вони перезаписують блоки кілька разів і лише потім викликають unlink. У сучасних SSD із wear-leveling і TRIM це не гарантує повного знищення, але значно ускладнює відновлення.

Багато дистрибутивів пропонують alias у .bashrc:

alias rm='rm -I --preserve-root'

Це змушує підтверджувати великі операції і захищає корінь.

Чек-лист перед використанням rm

  1. Перевірте поточний каталог командою pwd.
  2. Виведіть список того, що збираєтеся видалити (ls або find).
  3. Переконайтеся, що змінні середовища не порожні.
  4. Для рекурсивного видалення додайте -I або -i.
  5. Ніколи не запускайте rm -rf з шляхами, що містять лише / або * без додаткового шляху.
  6. Зробіть бекап критичних даних, якщо є хоч найменший сумнів.
  7. У скриптах додайте set -u (errexit на невизначені змінні) і перевірки існування каталогів.

Цей список варто тримати під рукою, особливо коли працюєте під root або в автоматизованих пайплайнах.

Питання, які часто шукають користувачі

Чи можна відновити файл після rm?
Так, якщо блоки ще не перезаписані. Використовуйте photorec, testdisk або debugfs для ext-файлових систем. Чим швидше — тим вища ймовірність успіху.

Чим rm відрізняється від rmdir?
rmdir видаляє лише порожні каталоги. rm -d робить те саме, але -r дозволяє видаляти непорожні.

Чому rm -rf / не працює в нових системах?
GNU coreutils з версії 6.4 за замовчуванням має –preserve-root. Щоб обійти, потрібен явний –no-preserve-root, який майже ніколи не варто використовувати.

Як видалити файл з ім’ям, що починається з дефіса?
rm -- -strange-name або rm ./-strange-name.

Чи безпечно використовувати rm у cron?
Тільки з повними шляхами, перевірками змінних і мінімальними правами. Краще використовувати find з -delete, який працює атомарніше.

Команда rm залишається одним із найпотужніших і водночас найнебезпечніших інструментів Unix. Розуміння її внутрішньої логіки, історії опцій і звичка перевіряти перед запуском перетворюють її з джерела страху на надійний робочий інструмент. Використовуйте її свідомо — і вона служитиме роками без сюрпризів.