Команда Linux `mv`: Повний технічний довідник та посібник з розширеного використання
Команда mv в Linux переміщує або перейменовує файли та директорії, оновлюючи метадані файлової системи — зокрема запис у директорії — без копіювання даних при роботі в межах однієї файлової системи. Це робить її атомарною, майже миттєвою операцією для переміщень у межах одного розділу, незалежно від розміру файлу.
Розуміння цієї відмінності відрізняє звичайних користувачів від адміністраторів, які можуть діагностувати, чому переміщення між двома точками монтування поводиться інакше, ніж у межах одного розділу, чому певні операції mv викликають дисковий I/O, а інші — ні, і як безпечно використовувати команду у виробничих середовищах, де цілісність даних є обов’язковою.
Що насправді робить команда mv під капотом
Коли ви виконуєте mv source destination в межах однієї файлової системи, ядро викликає rename(2) — єдиний системний виклик, який атомарно перепризначає запис у директорії. Жодні дані не зчитуються і не записуються на диск. Номер inode залишається незмінним; змінюється лише шлях.
Коли джерело та призначення знаходяться на різних файлових системах (різні розділи, NFS-монтування або bind-монтування), mv переходить до послідовності копіювання з подальшим видаленням: зчитує дані джерела, записує їх у призначення та від’єднує джерело лише після успішного запису. Це має критичні наслідки:
- Перервані переміщення між файловими системами можуть залишити неповну копію в місці призначення та оригінал у джерелі, або — у найгіршому випадку — видалити джерело до завершення запису.
- Переміщення великих файлів між файловими системами споживає пропускну здатність I/O та час, пропорційні розміру файлу.
- Права доступу та власність можуть не передаватися коректно, якщо цільова файлова система не підтримує ту саму модель прав (наприклад, FAT32, деякі мережеві ресурси).
Ця поведінкова відмінність невидима з синтаксису команди, але є фундаментальною для рішень системного адміністрування на серверах, що працюють на VPS Хостингу або Виділених Серверах з кількома точками монтування.
Синтаксис та основні параметри
mv [OPTIONS] SOURCE DESTINATION
mv [OPTIONS] SOURCE... DIRECTORYАргументи:
SOURCE — Один або кілька файлів чи директорій для переміщення або перейменування.
DESTINATION — Цільовий шлях. Якщо це існуюча директорія, джерело розміщується всередині неї. Якщо це неіснуючий шлях, джерело перейменовується на цей шлях.
Повний довідник параметрів
Параметр
Повна форма
Поведінка
-i
--interactive
Запитує підтвердження перед перезаписом існуючого файлу
-f
--force
Пригнічує всі запити; перезаписує без підтвердження
-n
--no-clobber
Ніколи не перезаписує існуючий файл; мовчки пропускає
-u
--update
Переміщує лише якщо джерело новіше за призначення або призначення відсутнє
-v
--verbose
Виводить ім’я кожного файлу під час обробки
-b
--backup
Створює резервну копію кожного файлу, який буде перезаписано
--suffix=SUFFIX
--suffix
Визначає суфікс резервної копії (за замовчуванням ~)
--strip-trailing-slashes
—
Видаляє кінцеві слеші з аргументів джерела
-t DIR
--target-directory
Переміщує всі джерела до вказаної директорії
-T
--no-target-directory
Розглядає призначення як звичайний файл, а не директорію
Примітка: Прапорець -r / -R, згаданий у багатьох посібниках, не існує в GNU mv. На відміну від cp, команда mv переміщує директорії рекурсивно за замовчуванням, оскільки працює з записами директорій, а не з вмістом файлів. Передача -r до mv у більшості дистрибутивів Linux призведе до помилки або буде мовчки проігнорована залежно від реалізації.
Базові операції з точними прикладами
Переміщення файлу до іншої директорії
mv /home/user/report.txt /var/backups/
Файл report.txt переміщується до /var/backups/. Якщо /var/backups/ знаходиться в тій самій файловій системі, що й /home/user/, це відбувається миттєво. Якщо ні — дані фізично копіюються.
Перейменування файлу на місці
mv old_config.conf new_config.conf
Обидва шляхи мають спільну батьківську директорію, тому це чистий виклик rename(2) — без переміщення даних, без I/O.
Переміщення кількох файлів до директорії
mv file1.txt file2.txt file3.txt /var/www/html/assets/
Коли вказано кілька джерел, призначення обов’язково має бути існуючою директорією. Якщо вона не існує, mv поверне помилку.
Переміщення директорії
mv /home/user/project /opt/projects/
Все дерево директорій — включно з усіма вкладеними файлами та піддиректоріями — переміщується як єдина атомарна операція в межах однієї файлової системи. Прапорець -r не потрібен і не приймається.
Розширені шаблони використання
Використання --backup для запобігання випадковій втраті даних
Параметр --backup є одним із найменш використовуваних механізмів безпеки в mv. Він створює версійну резервну копію будь-якого файлу, який буде перезаписано:
mv --backup=numbered config.yml /etc/app/config.yml
Це створює /etc/app/config.yml.~1~, .~2~ і так далі для послідовних перезаписів. В автоматизованих скриптах розгортання цей шаблон забезпечує легкий механізм відкату без спеціального інструменту резервного копіювання.
Режими керування резервними копіями:
none / off — Без резервної копії (поведінка за замовчуванням без --backup)
simple / never — Завжди створює просту резервну копію з суфіксом ~numbered / t — Створює нумеровані резервні копії (.~1~, .~2~, …)existing / nil — Використовує нумеровані резервні копії, якщо вони вже існують; інакше — простіУмовні переміщення з --update
mv --update /tmp/processed/*.csv /data/archive/Переміщуватимуться лише файли з /tmp/processed/, які новіші за відповідні файли в /data/archive/. Файли з однаковими або старішими мітками часу залишаються незмінними. Це особливо корисно в ETL-конвеєрах та скриптах ротації логів, де важлива ідемпотентність.
Використання -t для зручного синтаксису в скриптах
Параметр --target-directory інвертує порядок аргументів, роблячи його сумісним з конвеєрами xargs та find:
find /var/log -name "*.log.gz" -mtime +30 | xargs mv -t /mnt/cold-storage/logs/Без -t xargs потрібно було б формувати список аргументів інакше. Цей шаблон значно надійніший у виробничій автоматизації.
Поєднання --no-clobber з детальним виведенням
mv -nv *.conf /etc/app/conf.d/Це переміщує всі файли .conf без перезапису існуючих і виводить кожне успішне переміщення до stdout. Комбінація ідеально підходить для безпечних, придатних для аудиту масових операцій.
Безпечне переміщення файлів між файловими системами
При переміщенні великих файлів або директорій між точками монтування розгляньте цей шаблон для забезпечення цілісності:
rsync -a --remove-source-files /source/path/ /destination/path/ &&
find /source/path -type d -empty -deletersync з --remove-source-files виконує перевірене копіювання з подальшим видаленням із контрольною сумою, чого mv не забезпечує для міжфайлових операцій. Використовуйте цей підхід для критичних міграцій даних на виробничих серверах.
Практичні випадки використання в системному адмініструванні
Ротація логів застосунків
mv /var/log/nginx/access.log /var/log/nginx/access.log.$(date +%Y%m%d)
kill -USR1 $(cat /var/run/nginx.pid)Це перейменовує активний файл логу та сигналізує Nginx перевідкрити дескриптор файлу логу. Комбінація є основою ручної ротації логів до того, як logrotate виконає її автоматично.
Атомарне розгортання конфігураційних файлів
mv --backup=numbered /tmp/nginx.conf /etc/nginx/nginx.conf
nginx -t && systemctl reload nginxРезервна копія гарантує збереження попередньої конфігурації, якщо нова не пройде перевірку.
Організація ресурсів веб-сервера
На сервері, що запускає веб-застосунок, масова організація завантажених файлів за типом:
mv /var/www/uploads/*.jpg /var/www/uploads/images/
mv /var/www/uploads/*.pdf /var/www/uploads/documents/
mv /var/www/uploads/*.mp4 /var/www/uploads/video/Такий структурований менеджмент ресурсів поширений на серверах, що розміщують сайти через Спільний Веб-Хостинг або керовані середовища VPS з cPanel.
Поетапне оновлення SSL-сертифікатів
При управлінні вручну оновленими сертифікатами mv з резервним копіюванням є безпечним шаблоном розгортання:
mv --backup=simple /etc/ssl/certs/domain.crt /etc/ssl/certs/domain.crt.bak
mv /tmp/new_domain.crt /etc/ssl/certs/domain.crtДля автоматизованого управління сертифікатами поєднання цього з належно налаштованим сервісом SSL Сертифікатів повністю усуває потребу в ручній ротації.
Архівування поштових даних на поштовому сервері
На сервері, що запускає поштові служби, переміщення оброблених поштових скриньок до холодного сховища:
mv --update /var/mail/processed/ /mnt/archive/mail/$(date +%Y-%m)/Це безпосередньо застосовується до середовищ, що використовують виділену інфраструктуру Email Хостингу, де управління поштовими скриньками виконується на рівні файлової системи.
mv проти cp + rm проти rsync: Коли що використовувати
| Сценарій | Найкращий інструмент | Причина |
|---|---|---|
| Перейменування або переміщення в межах однієї файлової системи | mv | Атомарний системний виклик rename(2); нульовий I/O |
| Переміщення між файловими системами, малі файли | mv | Прийнятно; копіювання з подальшим видаленням відбувається автоматично |
| Переміщення між файловими системами, великі або критичні дані | rsync --remove-source-files | Перевірка контрольної суми; можливість відновлення |
| Переміщення з дедуплікацією або контролем пропускної здатності | rsync | Підтримує --bwlimit, --checksum, дельта-передачу |
| Переміщення із збереженням джерела | cp з подальшою перевіркою | Явний контроль над обома копіями |
| Переміщення з перетворенням (стиснення тощо) | Власний скрипт | mv не перетворює дані |
| Масове переміщення з фільтрацією | find + mv -t | Точний контроль над критеріями вибору |
Поширені підводні камені та як їх уникнути
Неоднозначність кінцевого слешу з директоріями:
mv directory_a/ directory_bЯкщо directory_b існує, directory_a розміщується *всередині* directory_b, що призводить до directory_b/directory_a/. Якщо directory_b не існує, directory_a перейменовується на directory_b. Така поведінка дивує багатьох адміністраторів. Використовуйте mv -T, щоб змусити розглядати призначення як шлях до файлу, а не як директорію-контейнер.
Розгортання символів підстановки без збігів:
mv *.log /archive/Якщо файли .log не існують, оболонка розгортає *.log до літерального рядка *.log, і mv намагається перемістити файл із буквальною назвою *.log, що призводить до незрозумілої помилки. Використовуйте nullglob у bash-скриптах:
shopt -s nullglob
files=(*.log)
[[ ${#files[@]} -gt 0 ]] && mv "${files[@]}" /archive/Стани гонки в конкурентних середовищах:
Кілька процесів, що переміщують файли зі спільної директорії черги, можуть спричиняти конфлікти. Використовуйте mv з унікальним тимчасовим іменем, а потім атомарно перейменовуйте:
mv /spool/job_123.tmp /spool/processing/job_123.workОскільки rename(2) є атомарним, цей шаблон безпечний для черг завдань у межах однієї файлової системи.
Переміщення файлів з іменами, що починаються з дефісу:
mv -- -oddfile.txt /destination/-- сигналізує про кінець параметрів, запобігаючи інтерпретації -oddfile.txt як прапорця.
Права доступу після переміщення між файловими системами:
mv не зберігає розширені атрибути (xattrs), ACL або контексти SELinux для всіх типів файлових систем. Після переміщення між файловими системами перевірте за допомогою:
ls -lZ /destination/file
getfattr -d /destination/fileНадійне використання mv у скриптах для виробництва
Для будь-якого скрипту, що використовує mv у виробничому контексті, застосовуйте ці практики беззастережно:
#!/usr/bin/env bash
set -euo pipefail
SOURCE="/var/data/export"
DEST="/mnt/nas/backup/$(date +%Y%m%d)"
# Verify source exists
[[ -e "$SOURCE" ]] || { echo "Source not found: $SOURCE" >&2; exit 1; }
# Verify destination is writable
mkdir -p "$DEST"
[[ -w "$DEST" ]] || { echo "Destination not writable: $DEST" >&2; exit 1; }
# Perform move with verbose output for logging
mv -v "$SOURCE" "$DEST/"set -euo pipefailзабезпечує завершення скрипту при будь-якій помилці, невизначеній змінній або збої в конвеєрі.- Явні перевірки існування та доступності для запису запобігають мовчазним збоям.
- Детальне виведення створює журнал аудиту в системних логах.
Матриця рішень: Вибір правильних параметрів mv
| Ситуація | Рекомендовані прапорці |
|---|---|
| Інтерактивний режим, один файл, невідомий стан призначення | -i -v |
| Автоматизований скрипт, призначення не повинно перезаписуватися | -n |
| Автоматизований скрипт, завжди перезаписувати | -f |
| Розгортання з можливістю відкату | --backup=numbered |
| Переміщення у стилі синхронізації, лише новіші файли | -u |
Масове переміщення через find або xargs | -t /destination/ |
| Налагодження скрипту | -v |
| Файли зі спеціальними іменами (дефіси, пробіли) | -- перед джерелом |
Ключові технічні висновки
mvв межах однієї файлової системи є атомарним і не створює дискового I/O — це операція лише з метаданими черезrename(2).mvміж файловими системами є послідовним копіюванням з подальшим видаленням; розглядайте його якcpпри плануванні надійності.- У GNU
mvнемає прапорця-r— директорії переміщуються рекурсивно за замовчуванням. --backup=numberedє найменш використовуваною функцією безпеки у виробництві вmv.--no-clobber(-n) та--force(-f) є взаємовиключними; перемагає останній вказаний.- Для критичних міграцій даних між файловими системами
rsync --remove-source-filesзабезпечує перевірку контрольної суми, якоїmvне може надати. - Завжди беріть змінні в лапки у скриптах і використовуйте
--для обробки імен файлів зі спеціальними символами. - Перевіряйте контексти SELinux та ACL після будь-якого переміщення між файловими системами у захищених середовищах.
Часті запитання
Чи працює mv по-різному на SSD порівняно з HDD?
Для переміщень у межах однієї файлової системи — ні, операція є оновленням метаданих незалежно від апаратного забезпечення зберігання. Для переміщень між файловими системами SSD скорочує реальний час фази копіювання, але логічна поведінка та ризики ідентичні.
Чому mv іноді займає багато часу навіть для малого файлу?
Якщо джерело та призначення знаходяться на різних файлових системах — включно з NFS-монтуваннями, tmpfs або окремими розділами — mv виконує повне копіювання. Навіть малий файл, переміщений через повільне мережеве монтування, буде переміщуватися повільно. Перевірте за допомогою df -h source destination, чи вони спільно використовують файлову систему.
Чи можна використовувати mv для переміщення файлів між контейнерами Docker або томами?
Не безпосередньо. Томи Docker є окремими просторами імен файлової системи. mv в межах одного тому працює нормально, але переміщення даних між томами вимагає операцій у стилі cp, зазвичай через docker cp або спільне bind-монтування.
Що відбувається, якщо mv переривається в середині операції при переміщенні між файловими системами?
Вихідний файл залишається незмінним до завершення копіювання та успішного від’єднання. Якщо процес завершується після копіювання, але до від’єднання, існують обидві копії. Якщо завершується під час копіювання, залишається неповний файл призначення, а джерело залишається незмінним. Завжди перевіряйте обидва шляхи після перерваного переміщення між файловими системами mv.
Чи безпечно використовувати mv у завданнях cron без інтерактивних прапорців?
Так, за умови явного використання -f або -n для пригнічення будь-яких запитів (які спричинили б зависання завдання cron), перевірки шляхів перед виконанням та перенаправлення stdout і stderr до файлу логу для можливості аудиту.
