Кто устанавливает переменные окружения $ USER и $ USERNAME?

34

Кроме того, будут ли эти переменные всегда соответствовать текущему имени пользователя, вошедшего в систему (они соответствуют моей системе Debian)? Могу ли я предположить их доступность в других Unix-подобных системах?

Мне также любопытно, почему можно было бы whoamiвместо того, чтобы просто читать любую из этих переменных.

tshepang
источник
2
Глядя на manстраницу, whoamiвыдает имя, связанное с вашим эффективным идентификатором пользователя. Это означает, что он вернет что-то другое, если вы используете sudoили запускаете исполняемый файл setuid. Если вы sudoнастроили, попробуйте, sudo whoamiнапример.
Джозеф Р.
4
USERи USERNAMEявляются обычными переменными среды, что означает, что, если вы хотите, вы можете установить для них произвольные значения Просто введите USER=xyz. Другими словами, даже если эти переменные существуют, нет гарантии, что их значения соответствуют текущему зарегистрированному имени пользователя.
Уве
@ Uwe By guarantee, я имел в виду по умолчанию (т.е. предполагая, что пользователь не изменил их).
Чепанг
2
@Tshepang Как продолжение моего первого комментария: сравните результаты sudo whoamiиsudo echo $USER
Джозеф Р.
2
@JosephR. Ибо sudo echo $USERоболочка расширяется $USER, затем вызывает sudo. Так что, конечно, он не выдает такой же результат, как whoami. Как sudo whoami, sudo sh -c 'echo $USER'делает (обычно) выход root. Что касается вашего комментария об whoamiиспользовании EUID , обратите внимание, что sudo whoamiбудет выводиться, rootдаже если whoamiиспользуется UID. sudoнаборы как EUID и UID для команды он работает ( за исключением очень необычной ситуации , что вы явно настроить его вести себя иначе). Сравните sudo id -uс sudo id -ru.
Элия ​​Каган,

Ответы:

29

Это логин .

Справочная страница Linux login (1) гласит:

Значения $ HOME , $ USER , $ SHELL , $ PATH , $ LOGNAME и $ MAIL задаются в соответствии с соответствующими полями в записи пароля.

Справочная страница FreeBSD login (1) гласит:

Войти утилита вводит информацию в окружающую среду (см ENVIRON (7) ) с указанием на домашний каталог пользователя (HOME), командного интерпретатора (SHELL), путь поиска (PATH), тип терминала (TERM) и имя пользователя (как LOGNAME и USER) ,

В NetBSD , OpenBSD и OS X страниц человека говорят то же самое.

Вот исходный код от логина util-linux:

setenv("HOME", pwd->pw_dir, 0); /* legal to override */
setenv("USER", pwd->pw_name, 1);
setenv("SHELL", pwd->pw_shell, 1);
/* ... */
setenv("LOGNAME", pwd->pw_name, 1);

Вот исходный код от входа в FreeBSD:

(void)setenv("LOGNAME", username, 1);
(void)setenv("USER", username, 1);
(void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);
poige
источник
2
На моей коробке Fedora 16 у меня есть USERи USERNAMEset, и ваша команда только возвращается LOGNAME.
Джозеф Р.
1
@JosephR., К сожалению, у меня нет Fedora на руках, но я также изучил исходники FreeBSD, см. UPD ..
poige
Но это явно не тот случай с Fedora. Все, что я говорю, - loginэто не единственная установка этих переменных.
Джозеф Р.
1
Обратите внимание, что Linux - это просто ядро, у него нет loginкоманды. Операционные системы, использующие Linux в качестве ядра, могут свободно использовать любую реализацию, которая им нравится. Например, системы на основе Debian, как правило, используют ту из shadow-utils, а не util-linux.
Стефан
1
Обратите внимание, что loginчасто не вызывается при входе поверх sshили большинством графических менеджеров входа.
Стефан
11

Там нет правил. Некоторые снаряды, как tcshилиzsh устанавливают $LOGNAME. zshнаборы $USER.

Это может быть установлено некоторыми вещами, которые регистрируют вас, например login(как вызывается gettyпри входе в систему через терминал, а иногда и другими вещами, такими как in.rlogind) cron,,su , sudo, sshd, rshd, графические менеджеры входа или нет.

Если был логин, по моему опыту, $USER он обычно установлен (но он не может быть обновлен после изменения идентификатора пользователя (с помощью команд setuid) в этом сеансе входа в систему. POSIX требует, чтобы он $LOGNAMEбыл установлен при входе в систему (и cron).

Чтобы получить регистрационное имя переносимым, лучше всего использовать lognameкоманду (если не было никакого логина, он может ничего не возвращать). Чтобы получить идентификатор пользователя, используйте id -u. Чтобы получить одно имя , соответствующее текущему эффективного идентификатора пользователя: id -un. Чтобы получить их все (в большинстве случаев для каждого идентификатора пользователя есть только одно имя пользователя, но это не гарантируется):

perl -le 'while ($n = getpwent()) {print $n if getpwnam($n) == $>}'

Хотя это может не сработать в системах, где пользовательская база данных не может быть перечислена (как это иногда бывает с сетевыми пользовательскими базами данных, например).

Стефан Шазелас
источник
3

Вы, вероятно, хотите здесь полагаться на стандарт POSIX , поскольку в какой-то момент вы, вероятно, будете заботиться не только о входе пользователя в систему (управляемомlogin программой), но и о cronзаданиях и тому подобном.

Следовательно, вы должны знать, что POSIX требует, $LOGNAMEно не требует $USER. Например, $USERне может быть установлено cron, как указано в ответе Keith Thompson , который также ссылается на некоторую историю о том, как это связано с историей System-V против BSD:

... по крайней мере, в моей системе (Ubuntu 14.04) переменная окружения $ USER не установлена ​​для заданий cron. Вместо этого вы можете использовать $ LOGNAME, которая является частью среды для заданий cron.

В соответствии с справочной страницей environment (7) (введите man environment, чтобы прочитать ее), $ USER используется программами, производными от BSD, а $ LOGNAME - программами, производными от System-V.

nealmcb
источник
1

Если вы хотите использовать переменные среды (вместо whoamiили getpwentи getpwnam) и не уверены, что они всегда установлены одинаково во всех * NIX системах, попробуйте это в bash:

THIS_USER=${USER:-${USERNAME:-${LOGNAME}}}
echo ${THIS_USER}

Если после всего этого он еще пуст, значит, вы находитесь в довольно эзотерической системе. ;)

Джесси Чисхолм
источник