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.