Skąd powłoka zna dom (y)?


25

Każda powłoka ma ustawioną zmienną środowiskową $ HOME (np .:) /Users/lotolo. Jeśli mam csh, mogę, unsetenv HOMEa jeśli tak, to cdbędę w domu. Przetestowałem to również na bash ( unset HOME) i to samo zachowanie. Skąd więc powłoka wie, gdzie jest mój dom / other_user? Gdzie odczytuje te wartości?

To nie jest duplikatem ponieważ moje pytanie nie brzmi, jak ja wiem, ale jak robi się powłoki know- HOME. To zachowanie obejmuje także innych użytkowników.


1
@StephenKitt, nie duplikat. Tutaj mówimy o zachowaniu powłoki dla katalogu domowego bieżącego użytkownika.
Stéphane Chazelas

W prostym przypadku z /etc/passwd. Niektóre systemy mogą przechowywać te informacje w LDAP, serwerach NIS itp.
Satō Katsura,

1
Programy (w tym powłoki) po prostu wywołują getpwuid(3)lub podobnie. Niektóre systemy można skonfigurować do „zmiany trasy” w getpwuid(3)celu pobierania informacji z /etc/passwdLDAP, NIS, NIS + itp.
Satō Katsura,

@StephenKitt, patrz moja odpowiedź
Stéphane Chazelas

1
@ GAD3R, patrz dyskusja powyżej, StephenKitt wskazał już na ten sam duplikat (który od tego czasu wycofał), ale powyżej argumentuję (i patrz również moja odpowiedź), że to nie jest duplikat.
Stéphane Chazelas

Odpowiedzi:


33

W przypadku cshi tcshzapisuje wartość $HOMEzmiennej w momencie uruchomienia powłoki ( w jej $homezmiennej, jak zauważył @JdeBP ).

Jeśli rozbroisz to przed rozpoczęciem csh, zobaczysz coś takiego:

$ (unset HOME; csh -c cd)
cd: No home directory.

W przypadku bash(i większości innych powłok podobnych do Bourne'a) widzę inne zachowanie niż twoje.

bash-4.4$ unset HOME; cd
bash: cd: HOME not set

Zawartość $HOMEzmiennej jest inicjowana przez proces logowania na podstawie informacji przechowywanych w bazie danych użytkowników w stosunku do nazwy użytkownika .

Informacje o samej nazwie użytkownika nie zawsze są dostępne. Jedyną powłoką, którą z pewnością wie, jest identyfikator użytkownika procesu, który ją wykonuje, a kilku użytkowników (z różnymi katalogami domowymi) może współdzielić ten sam identyfikator użytkownika.

Więc kiedy $HOMEjuż zniknie, nie ma niezawodnego sposobu na odzyskanie go.

Zapytanie bazy danych użytkownika (ze getpwxxx()standardowym interfejsem API) dla katalogu głównego pierwszego użytkownika, który ma taki sam identyfikator użytkownika, jak ten, w którym uruchomiona jest powłoka, stanowiłoby jedynie przybliżenie (nie wspominając o tym, że baza danych użytkowników mogła ulec zmianie (lub strona główna) katalog jest definiowany jako wartość jednorazowa) od rozpoczęcia sesji logowania).

zsh to jedyna znana mi powłoka, która to robi:

$ env -u HOME ltrace -e getpw\* zsh -c 'cd && pwd'
zsh->getpwuid(1000, 0x496feb, 114, 0x7f9599004697)      = 0x7f95992fddc0
/home/chazelas
+++ exited (status 0) +++

Wszystkie inne powłoki, które próbowałem albo narzekać na ten rozbrojony HOME lub użyć /jako domyślnej wartości home.

Jednak zachowuje się inne zachowanie fish, które wydaje się pytać bazę danych o nazwę użytkownika zapisaną w $USERpliku, getpwuid()jeśli istnieje, lub wykonać polecenie, jeśli nie:

$ env -u HOME USER=bin ltrace -e getpw\* fish -c 'cd;pwd'
fish->getpwnam("bin")  = 0x7fd2beba3d80
fish: Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory
where the current user has write access.
fish: Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory
where the current user has write access.
--- SIGCHLD (Child exited) ---
/bin
+++ exited (status 0) +++


$ env -u HOME -u USER ltrace -e getpw\* fish -c 'cd;pwd'
fish->getpwuid(1000, 0x7f529eb4fb28, 0x12d8790, 0x7f529e858697) = 0x7f529eb51dc0
fish->getpwnam("chazelas")                                      = 0x7f529eb51d80
--- SIGCHLD (Child exited) ---
--- SIGCHLD (Child exited) ---
/home/chazelas
+++ exited (status 0) +++

SEGV, gdy użytkownik nie istnieje ( https://github.com/fish-shell/fish-shell/issues/3599 ):

$ env -u HOME USER=foo fish -c ''
zsh: segmentation fault  env -u HOME USER=foo fish -c ''

2
Przypuszczam, że możemy zgłosić ten problem! Bardzo fajna odpowiedź, dzięki!
LotoLo,

1
@LotoLo, tak, jestem zajęty budowaniem z fishgłową dewelopera, aby sprawdzić, czy błąd też tam jest. Edytować. Tak to jest.
Stéphane Chazelas

Teraz jestem ciekawy: która zmienna środowiskowa sprawia, że ​​powłoka jest maksymalnie nieprzyjazna dla użytkownika, jeśli jest rozbrojona? PATH? TERM? USER?
user1024,

Jest tu dziwna linia: „byłoby tylko przybliżeniem ...” Nawiasy też nie są w tym akapicie. Co to miało być?
mur

1
@muru Querying the user database... would only be...rzeczywiście nie tak jasne
edc65

6

Skąd więc powłoka wie, gdzie jest mój dom / other_user?

Nie ma Po prostu źle przeprowadzasz eksperyment. Jak widać z podręcznika powłoki C, cdpolecenie zmienia się na wartość homezmiennej, jeśli zostanie podana bez argumentów. Jeśli ta zmienna nie jest ustawiona, nie wie, gdzie zmienić katalog i wyświetla błąd:

machine: ~> set home = /
machine: / home / user> cd
maszyna: ~> dom rozbrojony
machine: /> cd
cd: Brak katalogu domowego
maszyna: /> 

Usuwasz niewłaściwą zmienną. Nie jest to HOMEzmienna środowiskowa, to homezmienna wewnętrzna powłoki C (inicjowana z wartości poprzedniej podczas uruchamiania powłoki, ale poza tym niezależna zmienna sama w sobie).


no na csh (przynajmniej na mojej wersji: „tcsh 6.18.01 (Astron) 2012-02-14 (x86_64-apple-darwin)”) to zmienna HOME przenosząca wartość domu. Ale jak powiedział @Stephane Chazelas, muszę rozbroić zmienną przed uruchomieniem powłoki, ponieważ na początku ustawi wartość HOME.
LotoLo,

Powyżej jest powłoka C, którą uruchomiłem na poręcznej maszynie OpenBSD i demonstruje jej zachowanie. To nawet nie jest powłoka TENEX C (choć taka jest taka sama).
JdeBP,

Tak, widziałem to ... cshtcsh
Pisałem na

0

System ustawił zmienną HOME podczas logowania na ścieżkę do katalogu domowego użytkownika. Ustawia to

  • gdm, kdm lub xdm dla sesji graficznych.
  • zaloguj się w sesjach konsoli, telnet i rlogin
  • sshd dla połączeń SSH

Możesz zmienić jego wartość, ale zwróć uwagę, ponieważ .bashrc, .profile, .xinitrc itp. Nie zostaną odczytane, jeśli nie znajdują się w katalogu domowym.


Ale mogę to rozbroić ($ HOME) ... prawda? A skąd ma wiedzieć, gdzie jest dom innego użytkownika?
LotoLo

1
możesz go zaktualizować za pomocą usermod -d HOME_DIRpolecenia, gdy tworzony jest nowy użytkownik. domyślna strona główna to / home / $ nazwa użytkownika i jest ona określana przez program logowania.
Dababi
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.