Хто встановлює змінні середовища $ USER та $ USERNAME?


34

Також, чи завжди ці змінні відповідатимуть ім'ям користувача, що ввійшов у даний момент (вони є в моїй системі Debian)? Чи можу я припустити їх наявність у інших системах Unix (-подобних)?

Мені також цікаво, чому можна використовувати whoamiзамість того, щоб просто прочитати будь-яку з цих змінних.


2
Переглядаючи manсторінку, whoamiповідомляє ім’я, пов’язане з вашим ефективним ідентифікатором користувача. Це означає, що він поверне щось інше, якщо ви використовуєте sudoабо запускаєте виконувану програму. Якщо ви sudoналаштували, спробуйте, sudo whoamiнаприклад.
Джозеф Р.

4
USERі USERNAMEє звичайними змінними середовища, що означає, що при бажанні ви можете встановити їх на довільні значення. Просто введіть USER=xyz. Іншими словами, навіть якщо ці змінні існують, немає гарантії, що їх значення відповідають поточному введеному користувачеві ім'я користувача.
Уве

@Uwe By guarantee, я мав на увазі за замовчуванням (тобто припускаючи, що користувач їх не змінив).
thepang

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 (1) написано:

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

На головній сторінці входу в FreeBSD (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);

2
У вікні Fedora 16 у мене є USERі USERNAMEналаштування, і ваша команда тільки повертаєтьсяLOGNAME .
Джозеф Р.

1
@JosephR., На жаль, у мене немає Fedora на руках, але я також заглянув у джерела FreeBSD, див. UPD ..
poige

Але це, очевидно, не так у Fedora. Все, що я говорю, - loginздається , це не єдине, що встановлює ці змінні.
Джозеф Р.

1
Зауважте, що Linux - це лише ядро, воно не має loginкоманди. ОС, які використовують Linux в якості свого ядра, можуть використовувати будь-яку реалізацію, яка їм подобається. Наприклад, системи на базі Debian, як правило, використовують ті з тіньових утиліт, а не util-linux.
Стефан Шазелас

1
Зауважте, що loginце часто не викликається під час входу через sshабо більшість графічних менеджерів входу.
Стефан Шазелас

11

Немає правила. Деякі оболонки подобаються tcshабо zshвстановлюються $LOGNAME. zshнабори $USER.

Це може бути встановлено деякими речами, в які ви входите в систему login (як посилається на gettyчас входу в термінал, а іноді й на інші речі, як-от in.rlogind) cron,su , sudo, sshd, rshd, графічні менеджери входу чи ні.

Якщо у мене був логін, на мій досвід, $USER зазвичай встановлено (але воно може не оновлюватися після зміни ідентифікатора користувача (за допомогою встановлених команд) у межах сеансу входу. 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не може бути встановлено кроном, як зазначено в an відповіді Кіт Томпсон , який також посилається на деяку історію щодо того, як це стосується історії System-V проти BSD:

... принаймні у моїй системі (Ubuntu 14.04) змінна середовища US USER не встановлена ​​для завдань cron. Натомість ви можете використовувати $ LOGNAME, який є частиною середовища для роботи з cron.

Відповідно до man-сторінки середовища (7) (введіть man Environment, щоб прочитати її), $ USER використовується програмами, отриманими BSD, а $ LOGNAME використовується програмами, отриманими системою V.


1

Якщо ви хочете використовувати змінні середовища (замість whoamiабо getpwentі getpwnam) і не впевнені, що вони завжди встановлені однаково у всіх * NIX системах, то спробуйте це в bash:

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

Якщо він все-таки порожній після цього, ви перебуваєте в досить езотеричній системі. ;)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.