Команда Linux `mv`: Полное техническое руководство и расширенное руководство по использованию
Команда mv в Linux перемещает или переименовывает файлы и каталоги, обновляя метаданные файловой системы — конкретно запись каталога — без копирования данных при работе в пределах одной файловой системы. Это делает её атомарной, практически мгновенной операцией для перемещений внутри одного раздела, независимо от размера файла.
Понимание этого различия отделяет рядовых пользователей от администраторов, которые могут диагностировать, почему перемещение между двумя точками монтирования ведёт себя иначе, чем перемещение внутри одного раздела, почему одни операции mv вызывают дисковый ввод-вывод, а другие — нет, и как безопасно использовать команду в производственных средах, где целостность данных не подлежит обсуждению.
Что команда mv делает под капотом
Когда вы выполняете mv source destination в пределах одной файловой системы, ядро вызывает rename(2) — единственный системный вызов, который атомарно переназначает запись каталога. Никакие данные не читаются и не записываются на диск. Номер inode остаётся неизменным; меняется только путь.
Когда источник и назначение находятся на разных файловых системах (разные разделы, NFS-монтирования или bind-монтирования), mv переходит к последовательности копирование-затем-удаление: читает данные источника, записывает их в место назначения и удаляет источник только после успешной записи. Это имеет критические последствия:
- Прерванные межфайловые перемещения могут оставить частичную копию в месте назначения и нетронутый оригинал в источнике, или — в худшем случае — удалить источник до завершения записи.
- Перемещение больших файлов между файловыми системами потребляет пропускную способность ввода-вывода и время, пропорциональные размеру файла.
- Права доступа и владение могут не переноситься корректно, если целевая файловая система не поддерживает ту же модель прав (например, 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) — без перемещения данных, без ввода-вывода.
Перемещение нескольких файлов в каталог
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 vs. cp + rm vs. rsync: когда что использовать
| Сценарий | Лучший инструмент | Причина |
|---|---|---|
| Переименование или перемещение в пределах одной файловой системы | mv | Атомарный системный вызов rename(2); нулевой ввод-вывод |
| Межфайловое перемещение, небольшие файлы | 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в пределах одной файловой системы является атомарным и не производит дискового ввода-вывода — это операция только с метаданными через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 прерывается в середине операции при межфайловом перемещении?
Исходный файл остаётся нетронутым до завершения копирования и успешного выполнения unlink. Если процесс завершается после копирования, но до unlink, существуют обе копии. Если завершается во время копирования, частичный файл назначения остаётся, а источник не тронут. Всегда проверяйте оба пути после прерванного межфайлового mv.
Безопасно ли использовать mv в заданиях cron без интерактивных флагов?
Да, при условии, что вы явно используете -f или -n для подавления любых запросов (которые могут вызвать зависание задания cron), проверяете пути перед выполнением и перенаправляете как stdout, так и stderr в файл лога для возможности аудита.
