chown в Linux: смена владельца и группы файлов в Ubuntu
chown (change owner) — команда смены владельца и группы файла или директории в Linux. Часто используется вместе с chmod при настройке прав веб-сервера, передаче файлов между пользователями и работе с Docker-волюмами. Разбираем синтаксис, рекурсивные операции, как не сломать симлинки и сохранять владельцев при бэкапах через rsync.
Что такое владелец и группа
Каждый файл и директория в Linux имеют двух связанных пользователей-носителей:
- Владелец (owner) — конкретный UID пользователя.
- Группа (group) — конкретный GID группы.
Эти атрибуты определяют, чьи права будут применяться к процессу, обращающемуся к файлу:
- Если UID процесса = UID владельца — применяются права
u(user). - Если процесс в группе файла — права
g(group). - Иначе — права
o(other).
Посмотреть владельца и группу:
ls -l /etc/passwd
# -rw-r--r-- 1 root root 2884 Apr 24 10:15 /etc/passwd
# │ │
# │ └── группа
# └─────── владелец
В /etc/passwd владелец root, группа root. Это типично для системных файлов.
Базовый синтаксис chown
chown [опции] <владелец>[:<группа>] <файл...>
Несколько форм:
# Сменить только владельца
sudo chown deploy file.txt
# Сменить и владельца, и группу
sudo chown deploy:developers file.txt
# Сменить только группу (через двоеточие без владельца)
sudo chown :developers file.txt
# Или через chgrp (то же самое)
sudo chgrp developers file.txt
# По UID/GID (если имена не определены)
sudo chown 1001:1001 file.txt
Без sudo чаще всего работать не будет: смена владельца требует прав root (обычный пользователь не может «подарить» свой файл другому).
Рекурсивный chown
# Сменить владельца всему дереву
sudo chown -R www-data:www-data /var/www/html
# Через find (то же, но с фильтром)
sudo find /var/www -type f -exec chown www-data:www-data {} +
Recursive безопаснее, чем chmod -R — здесь нет «лишних битов», только метаданные владельца меняются.
Сценарии использования
Передать веб-серверу
После клонирования репозитория или загрузки файлов:
sudo chown -R www-data:www-data /var/www/html
www-data — стандартный пользователь Apache и nginx на Ubuntu. PHP-FPM по умолчанию тоже работает под этим пользователем.
Деплой-пользователь
Для разделения ролей часто заводят отдельного пользователя deploy:
sudo useradd -m -s /bin/bash deploy
sudo chown -R deploy:deploy /var/www/myapp
# nginx в группе deploy для чтения файлов
sudo usermod -a -G deploy www-data
sudo chmod -R 750 /var/www/myapp
Логика: deploy загружает файлы (write), www-data только читает (read).
Docker-волюмы
После docker run -v ./data:/data ... файлы внутри ./data часто принадлежат root (если контейнер так создавал). Чтобы вернуть себе:
sudo chown -R $USER:$USER ./data
Или сразу запускать контейнер с конкретным UID:
docker run --user $(id -u):$(id -g) -v ./data:/data ...
Восстановление после смены имени пользователя
Если переименовали пользователя через usermod -l newname oldname, файлы остаются связанными со старым UID. Если UID тоже сменился — нужен chown:
sudo find / -uid <OLD_UID> -exec chown <newname> {} +
chown и симлинки
По умолчанию chown следует за симлинками — меняет владельца целевого файла, а не самого симлинка:
ls -l symlink
# lrwxrwxrwx 1 alice alice 9 May 4 12:00 symlink -> target.txt
sudo chown bob symlink
# меняет владельца target.txt, симлинк остался alice
Чтобы поменять владельца самого симлинка — флаг -h (no-dereference):
sudo chown -h bob symlink
# Теперь симлинк принадлежит bob, target.txt остался прежним
Это часто важно при восстановлении бэкапа с симлинками или настройке chroot-окружений.
Сохранение владельцев при копировании
cp по умолчанию устанавливает владельцем запускающего пользователя. Чтобы сохранить оригинального:
sudo cp -a source.txt destination.txt # сохраняет всё: владельца, группу, права, время
sudo cp --preserve=ownership src dst # только владельца
rsync сохраняет владельцев с флагами -aH (только если запущен от root):
# Полный бэкап с сохранением владельцев
sudo rsync -aHAX /home/ /backup/home/
-a = -rlptgoD, где og — сохранение owner и group. Без sudo сохранение не работает, потому что обычный пользователь не может задавать чужих владельцев.
chown vs chgrp
chgrp — алиас для смены только группы:
sudo chgrp developers file.txt
# идентично
sudo chown :developers file.txt
chgrp чуть удобнее в скриптах, когда нужно явно подчеркнуть смену группы. Функционально — то же самое.
Reference-режим: скопировать владельца с другого файла
# Сделать file2 с тем же владельцем и группой, что у file1
sudo chown --reference=file1 file2
Удобно при настройке группы файлов под образец:
# Все файлы в директории — как у /etc/nginx/nginx.conf
sudo chown --reference=/etc/nginx/nginx.conf /etc/nginx/sites-enabled/*
Поиск файлов без владельца
После удаления пользователя его файлы остаются с орфанным UID (UID без записи в /etc/passwd):
# Файлы без владельца
sudo find / -nouser 2>/dev/null
# Файлы без группы
sudo find / -nogroup 2>/dev/null
# Передать всё root:
sudo find / -nouser -exec chown root:root {} + 2>/dev/null
После удаления учётки регулярно проверяйте систему этой командой.
Распространённые ошибки
Recursive chown по симлинкам
chown -R alice /home/alice без флагов следует за симлинками. Если в /home/alice есть симлинк на /etc — chown пройдёт и поменяет владельца там. Решение — -P (no-dereference) для recursive:
sudo chown -RP alice:alice /home/alice
Забыли про скрытые файлы
chown -R user * не возьмёт .bashrc, .profile и другие dotfiles. Решение — указывать директорию, не glob:
sudo chown -R user:user /home/user
Менять владельца /etc или /var
sudo chown -R deploy:deploy /etc сломает систему. chown на системных директориях должен быть точечным — только конкретные файлы вашего приложения.
Несовпадение UID между хостом и контейнером
В Docker UID 1000 на хосте и в контейнере — разные пользователи. Если volume-mount — файлы будут принадлежать «другому» юзеру с тем же UID. Решение — образ с тем же UID или --user при запуске.
Аудит владельцев в /etc
В /etc все файлы должны принадлежать root, кроме нескольких исключений. Проверка:
# Файлы в /etc не от root
sudo find /etc -not -user root -ls
Если что-то нашлось — это или специальный случай (например, /etc/sudoers.d/ бывает с разными владельцами для подсистем), или аномалия, заслуживающая внимания.
Частые вопросы
Чем отличается chown от chmod?
chmod меняет права (что можно делать с файлом). chown меняет владельца и группу (кто им владеет). Это разные оси: можно поменять права, не трогая владельца, и наоборот. Часто используются вместе: sudo chown www-data:www-data /var/www && sudo chmod 755 /var/www.
Как сменить владельца на www-data для всей папки?
sudo chown -R www-data:www-data /var/www/html. Флаг -R рекурсивно проходит по всем поддиректориям и файлам. Если в директории есть симлинки, ведущие наружу — лучше добавить -P, чтобы не выйти за пределы папки.
Почему chown требует sudo?
Смена владельца — операция, которая может повлиять на безопасность системы. Обычный пользователь не может «подарить» свой файл другому пользователю (это могло бы использоваться для обхода дисковых квот или подделки авторства). Поэтому chown требует прав root.
Что делать, если после Docker файлы принадлежат root?
Самый простой вариант — sudo chown -R $USER:$USER ./mounted-dir. Чтобы не повторять каждый раз — запускайте контейнер с флагом --user $(id -u):$(id -g) или собирайте свой образ с правильным UID. На rootless Docker (podman или Docker rootless mode) проблема не возникает в принципе.
Как поменять только группу без смены владельца?
Двумя способами: sudo chgrp <group> file или sudo chown :<group> file. Двоеточие в начале без указанного владельца означает «трогать только группу». Функционально команды идентичны.
Что запомнить
chownменяет владельца и группу,chmod— права.- Базовый синтаксис:
chown user:group file. - Без
sudoобычно не работает — операция требует прав root. - Recursive:
-R. Симлинки в дереве — добавить-P(no-dereference). - Только группу:
chgrp group fileилиchown :group file. --reference=file1 file2копирует владельца с file1.- После Docker-mount:
sudo chown -R $USER:$USER ./dataили запуск контейнера с--user. - Орфанные файлы (без владельца):
find / -nouser— регулярный аудит после удаления пользователей.