su
Сменить пользователя в оболочке — su, su -, su -c, su -s; чем отличается от sudo -i
su (substitute user) запускает оболочку или одну команду от имени другого пользователя — по умолчанию root. Пароль спрашивается целевого пользователя; root может переключиться на кого угодно без пароля. Для разовой команды с правами root обычно удобнее sudo, а su чаще нужен, когда root запускает что-то от имени служебной учётной записи.
Синтаксис
su [опции] [-] [пользователь [аргументы…]]
su - alice # войти как alice с её окружением
su alice -c 'команда' # выполнить одну команду
su -s /bin/bash svc -c 'команда' # обойти nologin в /etc/passwd
Опции
| Опция | Что делает |
|---|---|
-, -l, --login | оболочка входа: чистое окружение, переход в домашний каталог, чтение ~/.profile |
-c 'команда' | выполнить одну команду через оболочка -c и выйти; код возврата — код команды |
-s оболочка | запустить указанную оболочку вместо той, что записана в /etc/passwd |
-m, -p | не трогать окружение: HOME, SHELL, USER остаются от вызывающего |
-w VAR1,VAR2 | при - сохранить перечисленные переменные |
-g группа | основная группа (только для root) |
-G группа | дополнительная группа (только для root) |
-P | выделить новый псевдотерминал |
Аргументы после имени пользователя передаются оболочке: в su alice -c 'echo $0 $1' x y переменная $0 будет x, $1 — y.
su, su - и sudo
| Команда | Чей пароль | Окружение | Каталог |
|---|---|---|---|
su alice | alice | HOME, SHELL, USER, LOGNAME — от alice, остальные переменные остаются твоими | текущий |
su - alice | alice | чистое окружение alice, читается ~/.profile | /home/alice |
su - | root | чистое окружение root | /root |
sudo -i | твой | как su -, но по правилам sudoers | /root |
sudo -u alice -i | твой | как su - alice | /home/alice |
sudo -s | твой | оболочка root, окружение почти твоё | текущий |
/sbin/nologin и служебные учётные записи
У служебных пользователей (www-data, nobody, созданных через useradd -r -s /usr/sbin/nologin) в /etc/passwd стоит оболочка /usr/sbin/nologin (то же, что /sbin/nologin). Она печатает «This account is currently not available.» и завершается с кодом 1 — поэтому su svc и su svc -c '…' не работают. Чтобы выполнить команду от такого пользователя, root явно задаёт оболочку: su -s /bin/bash svc -c '…' или пользуется sudo -u svc команда.
Примеры
# стать root с полноценным окружением
su -
sudo -i # то же, если пароль root не задан (как в Ubuntu)
# одна команда от имени alice; кавычки обязательны
su - alice -c 'whoami; pwd'
# переменные внутри -c раскрываются уже у alice — бери в одинарные кавычки
su - alice -c 'echo $HOME'
# служебный пользователь с nologin
useradd -r -s /usr/sbin/nologin svc
su svc -c id # This account is currently not available.
su -s /bin/bash svc -c id # работает
sudo -u svc id # работает, оболочку sudo не запускает
# передать одну переменную в чистое окружение
APP_ENV=prod su -w APP_ENV - alice -c 'echo $APP_ENV'
# запустить от alice с основной группой devs (только root)
su -g devs alice -c id
Подводные камни
suбез-оставляет твоё окружение.PATH, переменные приложения и текущий каталог остаются прежними, поэтому команда может вести себя не так, как при настоящем входе пользователя. Нужна «чистая» сессия — пишиsu -.-cпринимает одну строку.su alice -c ls -lвыполнит толькоls, а-lуйдёт в опции самогоsu. Бери команду в кавычки целиком.- Двойные кавычки раскрывает твоя оболочка. В
su - alice -c "echo $HOME"подставится/rootещё до запускаsu. Используй одинарные кавычки. - У root в Ubuntu нет пароля (в
/etc/shadowстоит*), так чтоsu -от обычного пользователя всегда завершается «Authentication failure». Используйsudo -i. - Без терминала
suне спросит пароль в скрипте: ввод изecho пароль | su …срабатывает лишь случайно и небезопасен. В скриптах root вызываетsuбез пароля, остальным нуженsudo -nс правиломNOPASSWD. - Просроченный пароль или учётная запись блокируют даже
suот root: «Your account has expired» или требование сменить пароль. Проверьchage -l пользователь. su -sдля nologin-пользователя — это осознанный обход: так можно, но не делай таким пользователям обычную оболочку в/etc/passwd.