Как запускать команды и скрипты от имени другого пользователя в Linux

Быстрые ссылки
Процессы имеют владельцев
Запуск скрипта от другого пользователя
Команда runuser
Что использовать в конкретном случае
Процессы имеют владельцев
Когда программа или скрипт запускается, Linux создаёт процесс. У процесса есть владелец — либо другой процесс, либо имя учётной записи пользователя, если запустил человек. Владельцем процесса обычно становится shell, который вы использовали для запуска программы.
Владение процессом определяет часть возможностей и окружения процесса: права доступа к файлам, умение привязываться к портам, возможности сигналов и т.п. В зависимости от способа запуска процесс наследует атрибуты родительского процесса или пользователя.
Важно: запускать программу от имени другого пользователя полезно, когда вы хотите, чтобы создаваемые файлы и изменения принадлежали именно этому пользователю.
Каждый раз, когда вы используете sudo, вы запускаете команду от имени другого пользователя. По умолчанию это root. Термин “super user do” встречается в разговорной речи, но точнее думать о sudo как о «выполнении под другим пользователем» — substitute user do.
С sudo можно запускать команды под любым пользователем, но чаще всего требуется иметь права root. А запуск программы под пользователем root — не то же самое, что запуск её как тот другой пользователь; процесс всё ещё будет работать с правами root, если вы не указали -u.
В этой статье показано, как именно запускать процесс от имени другого пользователя и как запускать команды внутри скрипта так, будто их выполнил этот пользователь.
Запуск скрипта от другого пользователя — пример с Mary и Dave
Предположим, на компьютере настроены несколько учётных записей: maryq и dave. У Mary в домашнем каталоге есть скрипт other-user.sh со следующим текстом:
#!/bin/bash
echo "Script name:" $0
echo "Working directory:" $(pwd)
echo "Script running as user:" $(whoami)Скрипт выводит имя скрипта ($0), текущую рабочую директорию (pwd) и имя пользователя, от которого работает скрипт (whoami).
Скопируйте этот текст в файл /home/maryq/other-user.sh (или в домашний каталог другого пользователя) и сделайте файл исполняемым только для владельца:
chmod u+x other-user.shПроверим список файлов:
lsПрава доступа (слева направо) читаются так:
- владелец: чтение, запись, выполнение;
- группа: чтение и запись;
- остальные: только чтение.
При таких правах скрипт может запускать только Mary и root. Если Mary запускает скрипт, вывод ожидаемый:
./other-user.shСкрипт сообщит, что рабочая директория — домашняя директория Mary, а владелец процесса — maryq.
Если Dave попытается запустить скрипт напрямую, он не сможет, если у него нет прав:
/home/maryq/other-user.shЕсли Dave имеет права root, он может запустить скрипт через sudo:
sudo /home/maryq/other-user.shЭто частичный успех: скрипт выполнится, но его владелец процесса будет root, а не maryq.
Чтобы процесс выполнялся именно от имени Mary, используйте опцию -u у sudo:
sudo -u maryq /home/maryq/other-user.shТеперь whoami внутри скрипта покажет maryq.
Добавим строку, которая записывает файл в домашний каталог Mary:
#!/bin/bash
echo "Script name:" $0
echo "Working directory:" $(pwd)
echo "Script running as user:" $(whoami)
echo "This is going into a file in /home/maryq/" > /home/maryq/mary.txtПоскольку мы запустили скрипт как maryq (sudo -u maryq ...), файл /home/maryq/mary.txt будет создан с владельцем maryq:
./other-user.sh
ls -hl mary.txtЭто то же поведение, как если бы Mary сама запустила скрипт.
См. также: как использовать chmod для управления правами.
Команда runuser
Внутри скриптов иногда удобнее использовать runuser — команда, специально созданная для запуска процесса от имени другого пользователя в сценариях, где сам скрипт выполняется от root. У runuser лучше обработка кода возврата запущенного процесса и меньшая накладная нагрузка по сравнению с sudo.
Требование: runuser должен запускаться от root. Это означает, что весь скрипт должен быть запущен с повышенными правами (например, сам скрипт запущен через sudo). Внутри такого скрипта вы можете использовать runuser без дополнительного sudo.
Пример чтения файла Mary с использованием runuser. Команда - (иногда -l) запускает логин‑шелл с окружением, близким к тому, что был бы у пользователя при обычном входе. Опция -c указывает команду для выполнения:
sudo runuser - maryq -c 'cat mary.txt'Обратите внимание: здесь не требуется полный путь к файлу — используется домашняя директория Mary в окружении её логин‑сессии.
Если Dave создаёт скрипт run-maryq.sh с содержимым:
#!/bin/bash
runuser -l maryq -c 'cat mary.txt'и делает его исполняемым:
chmod +x run-maryq.sh
./run-maryq.shто при попытке запуска обычным пользователем runuser выдаст ошибку. Если же запустить скрипт от root:
sudo ./run-maryq.sh— то всё выполнится так, как будто Mary выполнила cat mary.txt сама.
Что использовать: sudo или runuser
На командной строке особой разницы нет: sudo -u удобен и гибок. Поскольку runuser часто вызывается с sudo, многие предпочитают просто sudo -u и на командной строке, и в скриптах.
Однако, если ваш сценарий уже выполняется от root и вам нужна предсказуемая обработка кода возврата, более лёгкое окружение и меньшее поведение интерактивности — runuser предпочтительнее для скриптов.
Подытожим:
- Для одноразовых команд и интерактивной работы:
sudo -u;<команда> - Для вызова внутри скрипта, который запускается от root:
runuser -l.-c '<команда>'
Технические нюансы и подводные камни
Важно понимать, что переключение пользователя затрагивает не только UID/GID, но и окружение процесса (PATH, HOME, переменные окружения), текущую рабочую директорию и права доступа к файлам. Ниже — частые нюансы, которые важно учитывать.
Окружение (ENV):
sudo -uпо умолчанию сохраняет часть окружения, но можно применять-iили-Hуsudoчтобы инициализировать окружение целевого пользователя.runuser -lимитирует логин, устанавливая HOME, SHELL и другие переменные.Путь (PATH): команды могут находиться в разных местах для разных пользователей. Явно задавайте полный путь к бинарникам в скриптах для надёжности.
Права на файлы: даже если вы запустите процесс от имени пользователя, сам скрипт сохраняет владельца файла. При создании новых файлов они будут принадлежать тому пользователю, от имени которого выполнен процесс.
Sudoers: политики в /etc/sudoers и включённые конфигурации (например, Defaults env_reset) влияют на то, что остаётся в окружении после sudo. Не давайте избыточные права через sudoers.
Setuid: на современных системах установка бита setuid на скрипты небезопасна и часто игнорируется ядром. Не полагайтесь на setuid для скриптов.
SELinux/AppArmor: механизмы мандатного контроля доступа не привязаны только к UID. Они могут блокировать доступ даже при правильном UID.
NFS/разделы с root_squash: если файлы на NFS, root может быть отображён в nobody; тогда запуск от root не даст ожидаемых прав на сетевых FS.
Коды возврата:
sudoиrunuserвозвращают код запущенной команды, но поведение при пайпах и наборе команд может отличаться — тестируйте критические случаи.
Альтернативные подходы и сравнение команд
su: исторически
su -переключает сессию на другого пользователя. Для скриптовsu -cработать может, ноsudo/runuserчаще безопаснее и гибче.sudo -u: гибкий, поддерживает журналы (логирование), контроль через sudoers.
runuser: легче в скриптах при исполнении от root, лучше обрабатывает коды возврата, запускает логин‑окружение с
-l.setuid бинарников: безопасный вариант — написать маленький C‑программу‑обёртку с setuid, если нужна ограниченная функциональность от имени другого пользователя.
Практический плейбук: шаги для безопасного запуска скрипта от другого пользователя
- Определите цель: почему нужно запускать от другого пользователя?
- Проверьте, есть ли необходимость в правах root: если нет — используйте
sudo -uуказанного пользователя. - Настройте права на скрипт (
chmod) и владельца (chown) так, чтобы только нужные пользователи могли изменить файл. - Проверьте /etc/sudoers: выдайте минимально необходимые привилегии через
visudo. - Если скрипт будет запускаться от root и вызывает команды от лица другого пользователя, используйте
runuser -l.-c ' ' - Тестируйте: проверьте
whoami,pwd,id, права созданных файлов, PATH и переменные окружения. - Логирование: собирайте stdout/stderr в журнал; фиксируйте временные метки и UID.
- Учёт безопасности: минимизируйте передачу пользовательских переменных в команды; избегайте интерпретации пользовательского ввода в
-c.
Чеклист по ролям
Администратор:
- настройте sudoers минимально;
- тестируйте runuser в окружениях CI/CD;
- документируйте, кто и зачем может запускать команды от других пользователей.
Разработчик/автор скрипта:
- явно указывайте пути к бинарникам;
- не доверяйте произвольным переменным окружения;
- обрабатывайте коды возврата и ошибки.
Оператор/инженер поддержки:
- используйте
sudo -uдля быстрой проверки; - при проблемах проверяйте SELinux/Audit и логи sudo.
Шпаргалка — полезные команды
# Запустить команду от имени пользователя alice
sudo -u alice whoami
# Запустить скрипт от пользователя maryq
sudo -u maryq /home/maryq/other-user.sh
# Запустить логин‑шелл для maryq и выполнить команду
runuser -l maryq -c 'cat ~/mary.txt'
# Внутри скрипта, исполняемого от root
runuser -l targetuser -c 'some-command --option'
# Проверить текущего пользователя и UID
whoami
id
# Сделать скрипт исполняемым только для владельца
chmod u+x other-user.shКогда подход не сработает — типичные случаи
- Скрипт требует специфичных привилегий ядра, доступных только root — тогда
-uне поможет. - Среда запуска (cron, systemd) может использовать другое окружение и HOME; используйте полные пути и явно задавайте переменные.
- Ограничения sudoers (NOPASSWD, env_reset) могут предотвратить передачу переменных окружения.
- NFS с root_squash поменяет владельца root на nobody; тогда операции с файлами будут неожиданными.
Безопасность и конфиденциальность
- Не давайте скрипту больше привилегий, чем необходимо. Принцип минимальных привилегий — ключевой.
- Не храните пароли в скриптах. Используйте ключи и токены с ограниченным временем жизни.
- Учитывайте, что запуск команд
-cс динамическим содержимым может приводить к инъекциям. Экранируйте аргументы или используйте массивы аргументов. - Проверьте политики SELinux/AppArmor, если доступ к ресурсам блокируется.
Критерии приёмки
- Команда/скрипт выполняются под нужным пользователем (проверить
whoami). - Созданные файлы имеют ожидаемого владельца (
ls -l). - Окружение обеспечивает доступ к необходимым бинарникам (PATH) и конфигурациям.
- Логи содержат запись о выполнении и код возврата команды.
Краткое резюме
Важно различать владение файлом/скриптом и пользователя, от имени которого выполняется процесс. Для интерактивной работы и одноразовых задач чаще всего достаточно sudo -u . Для внутрискриптовых вызовов, когда скрипт запускается от root и требуется предсказуемое окружение и обработка кодов возврата — предпочтительнее runuser.
Важно протестировать поведение в вашей инфраструктуре с учётом sudoers, SELinux, NFS и особенностей окружения.
Важно: всегда применяйте принцип минимальных привилегий и логируйте выполнение команд.
Сводка: используйте sudo -u для простых случаев и интерактивных задач, runuser — для сценариев внутри скриптов, запускаемых от root.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента