{% youtube src="https://www.youtube.com/watch?v=dKaDTeNAm8k" %}{% endyoutube %}
Мы с вами уже выяснили, что Linux – система многопользовательская. Если с помощью команды wc посчитать количество строк в файле /etc/passwd:
cat /etc/passwd
wc -l /etc/passwd
где перечислены все пользователи, мы увидим, что сейчас в системе 48 пользователей. Среди них есть наш пользователь user, суперпользователь root, а остальные, которых создавали не мы, а система, считаются сервисными пользователями.
Нам сегодня понадобится ещё один пользователь, поэтому создадим его с помощью команды:
sudo useradd user2
введём наш пароль, а потом с помощью:
sudo passwd user2
зададим пароль для второго пользователя.
Начнём с команды su:
su
Она позволяет залогиниться каким-то пользователем или запускать команды от имени другого пользователя. При этом нужно знать пароль этого другого пользователя. Это бывает нужно, когда у нашего пользователя нет нужных прав, либо когда нам нужно запустить какой-то процесс от имени другого пользователя, например, в целях безопасности.
Например, сейчас мой пользователь не может зайти в директорию /home/user2:
cd /home/user2
потому что у него недостаточно прав. Я могу написать:
su user2
ввести пароль пользователя user2 и стать этим самым вторым пользователем, как видно в начале строки. А дальше смогу зайти в нужную директорию:
cd /home/user2
Чтобы вернуться к моему пользователю, я могу написать:
exit
либо нажать Ctrl+d. Если написать просто:
su
либо
su root
и ввести пароль рута, можно работать от пользователя root.
Но помните мы разбирали файлы ~/.bash_profile и ~/.bashrc ? Мы писали там переменные и алиасы, и, в случае с ~/.bash_profile, нам нужно было перезалогиниться, а в случае с ~/.bashrc нам достаточно было просто запустить новый эмулятор терминала. То есть ~/.bash_profile это файл настроек для login shell, а ~/.bashrc для nonlogin shell.
Давайте сделаем вот что. У пользователя user2:
su user2
в файле ~/.bash_profile:
nano /home/user2/.bash_profile
создадим переменную test1 равную test1:
test1=test1
а в файле ~/.bashrc:
nano /home/user2/.bashrc
переменную test2 равную test2:
test2=test2
Теперь выйдем - ctrl+d - заново зайдём:
su user2
и посмотрим, как обстоят дела с переменными:
echo $test1
echo $test2
Как видите, сработала настройка только из ~/.bashrc, то есть non-login shell. Это означает, что переменные окружения не прочитались с ~/.bash_profile (login shell) пользователя user2. На самом деле, все переменные остались от предыдущего пользователя. Допустим, если посмотреть переменную PATH:
echo $PATH
можно увидеть пути к директориям /home/user/bin, а это домашняя директория первого пользователя. Также, если писать su user2, можно заметить, что директория, в которой мы находимся, не меняется:
pwd
Зачастую нужно, чтобы при логине за другого пользователя поменялось окружение, то есть, чтобы применились настройки из ~/.bash_profile нужного пользователя. Для этого после su следует писать дефис:
su – user2
Теперь у меня есть обе переменные:
echo $test1
echo $test2
то есть считался файл ~/.bash_profile, а значит это был login shell. Также стоит заметить, что при su c дефисом поменялась и директория – раньше мы находились в домашней директории пользователя user, а после "su -" меняется текущая директория - /home/user2.
Кстати, чтобы понять, текущий shell – login или non-login, не обязательно выдумывать каждый раз какие-то проверки с переменными, достаточно проверить значение переменной $0:
echo $0
При non-login shell значение будет просто bash, а при login shell "-bash". И если проверить ту же переменную PATH:
echo $PATH
можно увидеть, что теперь здесь нет пути /home/user/bin, то есть переменные окружения не передались от предыдущего пользователя, а появились как следует.
Так вот, подводя итоги. Когда вы вводите свой логин и пароль, будь то удалённо с помощью ssh, либо локально, зайдя в виртуальный терминал, либо залогинившись в графической оболочке - запускается оболочка со входом - login shell. Это оболочка с авторизацией, она считывает настройки – те же переменные, алиасы, функции сначала с файла /etc/profile, где написано смотреть на файлы в директории /etc/profile.d/ и в файл ~/.bash_profile в домашней директории пользователя. Там также написано смотреть в файл ~/.bashrc в домашней директории пользователя, в котором также написано смотреть в файл /etc/bashrc.
Когда же вы запускаете программу эмулятор терминала, то там нет логина, вы без логина и пароля можете вводить команды - оболочка без входа - non-login shell. В случае с non-login shell сначала считывается файл ~/.bashrc в домашней директории пользователя, затем считывается файл /etc/bashrc, который в свою очередь ссылается на файлы в /etc/profile.d/. Но приведённая схема может отличаться на других дистрибутивах.
Кроме этого, оболочки делятся на interactive и non-interactive. Если вы логинитесь и запускаете команды - это interactive login shell. Если вы работаете в эмуляторе терминала - это interactive non-login shell. Когда работают скрипты, они обычно запускаются без всякого логина - тут уже non-interactive non-login shell. Да, когда вы запускаете эмулятор терминала, в этом эмуляторе запускается bash и запускает ~/.bashrc. Сами по себе ~/.bashrc и ~/.bash_profile - это просто набор команд в одном файле. То есть это скрипты. Когда же вы логинитесь, не важно каким образом, тоже запускается bash, при этом он запускает ~/.bash_profile.
Ладно, со сменой пользователя разобрались. Мы еще говорили, что su позволяет запускать команды от имени другого пользователя. Для этого используется ключ -c. Например:
su user2 -c "touch file"
su – user2 -с "touch file"
Подумайте, почему первая команда завершилась с ошибкой, а вторая без? Ну и зачастую, su используют чтобы работать от имени root пользователя, для примера запустим nano от рута:
su - -c "nano /etc/passwd"
и теперь мы можем редактировать файл /etc/passwd и в целом можем делать всё что угодно.
Кстати, если запускать su от имени рута:
su
su user2
то никаких паролей не потребуется, root может логиниться кем угодно.