Kto ustawia zmienne środowiskowe $ USER i $ USERNAME?


34

Czy te zmienne zawsze będą pasować do aktualnie zalogowanej nazwy użytkownika (robią to w moim systemie Debian)? Czy mogę założyć ich dostępność w innych systemach uniksowych?

Jestem również ciekawy, dlaczego można by użyć whoamizamiast po prostu czytać dowolną z tych zmiennych.


2
Patrząc na manstronę, whoamipodaje nazwę powiązaną z efektywnym identyfikatorem użytkownika. Co oznacza, że ​​zwróci coś innego, jeśli używasz sudolub uruchamiasz plik wykonywalny setuid. Jeśli sudoskonfigurowałeś, spróbuj sudo whoamina przykład.
— Joseph R.

4
USERi USERNAMEsą zwykłymi zmiennymi środowiskowymi, co oznacza, że ​​jeśli chcesz, możesz ustawić je na dowolne wartości. Po prostu wpisz USER=xyz. Innymi słowy, nawet jeśli te zmienne istnieją, nie ma gwarancji, że ich wartości odpowiadają aktualnie zalogowanej nazwie użytkownika.
— Uwe

@ Uwe By guarantee, miałem na myśli domyślnie (tzn. Zakładając, że użytkownik ich nie zmienił).
— tshepang

2
@Tshepang Jako kontynuacja mojego pierwszego komentarza: porównaj wyniki sudo whoamiisudo echo $USER
— Joseph R.

2
@JosephR. Ponieważ sudo echo $USERpowłoka rozszerza się $USER, a następnie wywołuje sudo. Więc oczywiście nie daje tego samego wyniku, co whoami. Podobnie sudo whoami, sudo sh -c 'echo $USER'robi (zwykle) wyjście root. Jeśli chodzi o komentarz na temat whoamiużywania identyfikatora EUID , zwróć uwagę, że sudo whoamibyłby generowany, rootnawet gdyby whoamiużywał identyfikatora UID. sudoustawia zarówno identyfikator EUID, jak i identyfikator UID dla uruchomionego polecenia (z wyjątkiem bardzo nietypowej sytuacji, w której jawnie skonfigurowano go, aby zachowywał się inaczej). Porównaj sudo id -uz sudo id -ru.
— Eliah Kagan

Odpowiedzi:


29

To login .

Strona podręcznika logowania do systemu Linux (1) mówi:

Wartości dla $ HOME , $ USER , $ SHELL , $ PATH , $ LOGNAME i $ MAIL są ustawiane zgodnie z odpowiednimi polami we wpisie hasła.

Strona podręcznika logowania do FreeBSD (1) mówi:

Logowanie narzędzie wprowadza informacje do środowiska (patrz environ (7) ) określający katalog użytkownika domowego (home), interpretera poleceń (Shell), ścieżka przeszukiwania (PATH), typ terminala (TERM) oraz nazwę użytkownika (zarówno LOGNAME i USER) .

W NetBSD , OpenBSD i OS X strony man powiedzieć to samo.

Oto kod źródłowy z loginu 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);

Oto kod źródłowy z loginu FreeBSD:

(void)setenv("LOGNAME", username, 1);
(void)setenv("USER", username, 1);
(void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);

2
Na moim pudełku Fedory 16 mam oba USERi USERNAMEustawione, a twoje polecenie tylko zwraca LOGNAME.
— Joseph R.

1
@JosephR., Niestety nie mam Fedory pod ręką, ale zajrzałem również do źródeł FreeBSD, patrz UPD ..
— poige

Ale oczywiście nie dotyczy to Fedory. Mówię tylko, loginże nie wydaje się być jedyną rzeczą ustawiającą te zmienne.
— Joseph R.

1
Zauważ, że Linux jest tylko jądrem, nie ma loginpolecenia. Systemy operacyjne wykorzystujące Linux jako jądro mogą swobodnie korzystać z dowolnej implementacji. Na przykład systemy oparte na Debianie mają tendencję do korzystania z tego z shadow-utils, a nie z ut-linux.
— Stéphane Chazelas

1
Należy pamiętać, że loginczęsto nie jest wywoływane podczas logowania się sshprzez większość graficznych menedżerów logowania.
— Stéphane Chazelas

11

Nie ma reguły. Niektóre muszle lubią tcshlub zshustawiają $LOGNAME. zshzestawy $USER.

To może być ustawiona przez niektórych rzeczy, które w niczym logowania login(jak wywoływane przez gettyprzy logowaniu na terminal, a czasem przez inne rzeczy, jak in.rlogind) cron, su, sudo, sshd, rshd, graficznych menedżerów logowania lub nie.

Z mojego doświadczenia $USERwynika jednak, że generalnie jest ustawiony (ale może nie zostać zaktualizowany po zmianie identyfikatora użytkownika (za pomocą komend setuid) w ramach tej sesji logowania. POSIX wymaga, aby $LOGNAMEbył ustawiony podczas logowania (i cron).

Aby uzyskać nazwę logowania przenośną, najlepiej użyć lognamepolecenia (jeśli nie było żadnego logowania, może nic nie zwrócić). Aby uzyskać identyfikator użytkownika, użyj id -u. Aby otrzymać jedną nazwę odpowiadającą aktualnej efektywny id użytkownika: id -un. Aby uzyskać je wszystkie (przez większość czasu na identyfikator użytkownika przypada tylko jedna nazwa użytkownika, ale nie jest to gwarantowane):

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

Chociaż może to nie działać w systemach, w których nie można wyliczyć bazy danych użytkowników (jak to czasami bywa na przykład w sieciowych bazach danych użytkowników).


3

Prawdopodobnie chcesz tutaj polegać na standardzie POSIX , ponieważ w pewnym momencie zapewne będziesz się martwić nie tylko logowaniem użytkownika (zarządzanym przez loginprogram), ale także cronzadaniami i tym podobnymi.

Dlatego powinieneś wiedzieć, że POSIX wymaga, $LOGNAMEale nie wymaga $USER. Np. $USERNie może być ustawiony przez crona, jak wskazano w odpowiedzi Keitha Thompsona , który również odwołuje się do historii, w jaki sposób odnosi się to do historii System-V vs BSD:

... przynajmniej w moim systemie (Ubuntu 14.04) zmienna środowiskowa $ USER nie jest ustawiona dla zadań cron. Zamiast tego możesz użyć $ LOGNAME, który jest częścią środowiska dla zadań cron.

Zgodnie ze stroną podręcznika środowiskowego środowiskowego (7, aby go odczytać, należy wpisać $ USER) w programach pochodnych BSD, a $ LOGNAME w programach pochodnych System-V.


1

Jeśli chcesz użyć zmiennych środowiskowych (zamiast whoamilub getpwenti getpwnam) i nie masz pewności, czy są one zawsze ustawione w ten sam sposób we wszystkich systemach * NIX, spróbuj tego w bash:

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

Jeśli mimo wszystko nadal jest pusty, oznacza to, że jesteś w dość ezoterycznym systemie. ;)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.