Как сохранить права доступа при копировании в Linux

Права файлов — важная часть спецификации Unix. Новички часто не замечают, что при копировании файл фактически создаётся заново, и его права зависят от текущего umask и привилегий пользователя. В результате разрешения у копии могут отличаться от исходного файла.
Ниже — практические способы сохранить права доступа при копировании, а также рекомендации, когда каждый метод лучше всего подходит.
Основные команды для сохранения прав
cp — простые копии
Команда cp поддерживает опцию для сохранения режима, владельца и меток времени.
cp -p source-file dest-fileДля директорий добавьте рекурсивность:
cp -rp source-dir/ dest-dir/Аналогично, режим «архива» сохраняет максимально возможное количество атрибутов:
cp -a source-dir/ dest-dir/Важно: cp -a пытается сохранить права, владельца и временные метки, а также символьные ссылки и контекст (по возможности). Чтобы сохранить владельца файла, вы должны запускать команду с правами root.
rsync — эффективное и гибкое копирование
rsync часто предпочитают за скорость и гибкость. Базовый пример:
rsync -a source-dir/ dest-dir/-generic опции для удобства вывода:
rsync -avh source-dir/ dest-dir/Чтобы дополнительно сохранить ACL и расширенные атрибуты (xattrs), используйте:
rsync -aAXv source-dir/ dest-dir/Заметка про слеш в конце пути: слеш после исходной директории (source-dir/) означает «копировать содержимое каталога», а без слеша — «копировать сам каталог как объект». Это часто влияет на итоговую структуру в dest-dir.
tar — архивирование с восстановлением прав
Для копирования с сохранением всех атрибутов удобно использовать поток tar:
cd /path && tar -cpf - source-dir | (cd /dest && tar -xpf -)tar надёжно переносит права, владельцев (если выполняется от root), ACL и xattrs при использовании соответствующих опций.
scp — удалённое копирование
scp поддерживает опцию -p, которая сохраняет времена доступа/изменения и режим. Однако для сохранения владельца на удалённой машине обычно требуются привилегии:
scp -p file user@host:/path/Проверка прав после копирования
Проверьте права и ACL:
getfacl source-file
getfacl dest-fileИли используйте stat / ls:
stat source-file
ls -l source-fileКогда способ может не сработать и как это исправить
Important: Сохранение владельца или некоторых атрибутов требует соответствующих прав (обычно root). Другие причины проблем и их решения:
- ACL и xattrs не копируются по умолчанию. Решение: rsync -aAX или tar с опциями для xattr/ACL.
- SELinux-контекст может не сохраниться без специальных опций. Решение: tar сохраняет контексты при правильной конфигурации; rsync может требовать дополнительных флагов/плагинов.
- Разные файловые системы (например, ext4 → FAT) не поддерживают некоторые атрибуты. Решение: используйте файловые системы с поддержкой нужных атрибутов или перенесите их отдельно.
- Копирование между пользователями/хостами: чтобы сохранить владельца, выполняйте операции от root или используйте sudo на обеих сторонах.
Быстрые правила и модель мышления
Ментальная модель: при копировании создаётся «новый» inode, и на него действует umask и права процесса. Команды с флагом «preserve/архив» пытаются переустановить исходные атрибуты после создания файла.
Эвристики:
- Если нужна точная копия атрибутов (включая ACL/xattr/SELinux) — используйте rsync -aAX или tar.
- Для повседневного копирования директорий на локальной машине достаточно cp -a.
- Для больших наборов данных, где нужно экономить трафик, используйте rsync.
Сравнение: cp vs rsync vs tar vs scp
- cp -a: просто и локально, сохраняет базовые атрибуты; требует root для владельца.
- rsync -a / -aAX: лучший выбор для больших объёмов, при синхронизации и для копирования ACL/xattr.
- tar: универсален при переносе между файловыми системами и сохранении максимума атрибутов.
- scp -p: удобно для простых удалённых копий, но ограничено и зависит от прав.
Чек-листы по ролям
Администратор (root):
- Использовать rsync -aAX или tar -p для полного переноса.
- Проверить getfacl и stat после копии.
- При необходимости скорректировать SELinux контексты (restorecon).
Обычный пользователь:
- Использовать cp -a для локальных копий.
- Если нужно сохранить только время и режим — cp -p или scp -p.
- Попросить администратора при необходимости сохранить владельца/ACL.
Шпаргалка команд
- cp -p file dest
- cp -rp dir/ dest/
- cp -a dir/ dest/
- rsync -avh source/ dest/
- rsync -aAXv source/ dest/
- tar -cpf - dir | (cd /dest && tar -xpf -)
- scp -p file user@host:/path/
- getfacl file
- stat file
Критерии приёмки
- Права совпадают: вывод getfacl на источнике и на копии эквивалентен.
- Владелец совпадает (если задача требовала этого) и операция выполнялась с нужными привилегиями.
- SELinux-контексты и ACL — сохранены при необходимости.
Дополнительные рекомендации и безопасность
- Перед массовым копированием протестируйте метод на паре файлов и проверьте getfacl.
- При переносе через сеть используйте шифрование (rsync через ssh, scp).
- Не забывайте про backup перед изменением прав/владельцев в продакшене.
Короткое резюме
Используйте cp -a для простых локальных случаев и rsync -a (или rsync -aAX для ACL/xattr) для надёжного и эффективного копирования. Tar остаётся универсальным инструментом для точного восстановления прав при переносе между файловыми системами. Всегда проверяйте результат командами getfacl, stat или ls -l.
Important: чтобы сохранять владельца и некоторые атрибуты, команды должны выполняться с соответствующими правами (обычно root).
Похожие материалы
Оформление профиля в Medium для авторов
Установка второго IDE‑жёсткого диска
Ускорение загрузки в OneDrive: проверки и исправления
Как обновить Visual Studio на ПК
AppImage Pool: клиент AppImageHub для Linux