Woher weiß eine Muschel, zu Hause?

25

Für jede Shell ist eine Umgebungsvariable $ HOME festgelegt (Beispiel:) /Users/lotolo. Wenn ich unter CSH bin, kann ich unsetenv HOMEund wenn ich das tue, cdbin ich in meinem Haus. Ich habe dies auch mit bash ( unset HOME) getestet und es ist das gleiche Verhalten. Woher weiß die Shell, wo mein / other_user zu Hause ist? Wo liest es diese Werte?

Dies ist kein Duplikat, da meine Frage nicht lautet, woher ich es weiß, sondern woher die Shell es weiß HOME. Und dieses Verhalten wird auch auf andere Benutzer ausgeweitet.

LotoLo
quelle
1
@ StephenKitt, nein, kein Duplikat. Hier geht es um das Shell-Verhalten für das Home-Verzeichnis des aktuellen Benutzers.
Stéphane Chazelas
Im einfachen Fall von /etc/passwd. Einige Systeme können diese Informationen in LDAP-, NIS-Servern usw. speichern.
Satō Katsura,
1
Programme (einschließlich Shells) rufen einfach getpwuid(3)oder ähnliches auf. Einige Systeme können so konfiguriert werden, dass sie getpwuid(3)Informationen von /etc/passwdLDAP, NIS, NIS + usw. "
Satō Katsura,
@ StephenKitt, siehe meine Antwort
Stéphane Chazelas
1
@ GAD3R, siehe obige Diskussion, StephenKitt hatte bereits auf dasselbe Duplikat hingewiesen (das er seitdem zurückgezogen hat), aber ich argumentiere oben (und sehe auch meine Antwort), dass es kein Duplikat ist.
Stéphane Chazelas

Antworten:

33

Im Fall von cshund tcshwird der Wert der $HOMEVariablen zum Zeitpunkt des Starts der Shell aufgezeichnet ( in ihrer $homeVariablen, wie von @JdeBP angegeben ).

Wenn Sie es vor dem Start deaktivieren, wird Folgendes angezeigt csh:

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

Bei bash(und den meisten anderen Bourne-ähnlichen Muscheln) sehe ich ein anderes Verhalten als bei Ihnen.

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

Der Inhalt der $HOMEVariablen wird durch den Anmeldeprozess in der Benutzerdatenbank gegen den Benutzer gespeichert sind, basierend auf Informationen initialisiert Namen .

Die Informationen zum Benutzernamen selbst sind nicht immer verfügbar. Alles, was eine Shell mit Sicherheit wissen kann, ist die Benutzer-ID des Prozesses, der sie ausführt, und mehrere Benutzer (mit unterschiedlichen Basisverzeichnissen) können dieselbe Benutzer-ID verwenden.

Also, wenn $HOMEes einmal weg ist, gibt es keinen zuverlässigen Weg, es zurückzubekommen.

Das Abfragen der Benutzerdatenbank (mit getpwxxx()Standard-API) nach dem Basisverzeichnis des ersten Benutzers, der dieselbe Benutzer-ID wie dasjenige hat, auf dem die Shell ausgeführt wird, wäre nur eine Annäherung (ganz zu schweigen von der Tatsache, dass sich die Benutzerdatenbank geändert haben könnte (oder die Basis) Verzeichnis wird seit dem Start der Anmeldesitzung als einmaliger Wert definiert.

zsh ist die einzige Shell, von der ich weiß, dass sie das macht:

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

Alle anderen Shells, die ich versucht habe, beschweren sich entweder über dieses nicht eingestellte HOME oder verwenden es /als Standard-Home-Wert.

Ein anderes Verhalten ist jedoch fishdas, bei dem die Datenbank nach dem Benutzernamen abgefragt wird, in dem er gespeichert $USERist, oder getpwuid()wenn nicht:

$ 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, wenn der Benutzer nicht existiert ( 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 ''
Stéphane Chazelas
quelle
2
Ich nehme an, wir können dieses Problem melden! Sehr nette Antwort übrigens, danke!
LotoLo
1
@LotoLo, ja, ich baue gerade mit dem Devgit- fishKopf, um zu sehen, ob der Bug auch da ist. Bearbeiten. Ja ist es.
Stéphane Chazelas
Jetzt bin ich gespannt: Welche Umgebungsvariable macht die Shell maximal benutzerunfreundlich, wenn sie nicht gesetzt ist? PATH? TERM? USER?
user1024
Es gibt hier eine ungerade Zeile: "wäre nur eine Annäherung ..." Die Klammern stehen auch in diesem Absatz nicht in einer Linie. Was sollte es sein?
Muru
1
@muru Querying the user database... in der would only be...Tat nicht so klar
edc65
6

Woher weiß die Shell, wo mein / other_user zu Hause ist?

Das tut es nicht. Sie führen das Experiment einfach nicht richtig durch. Wie Sie dem C-Shell-Handbuch entnehmen können, cdändert sich der Befehl in den Wert der homeVariablen, wenn keine Argumente angegeben werden. Wenn diese Variable nicht gesetzt ist, weiß sie nicht, wohin sie das Verzeichnis wechseln soll, und gibt einen Fehler aus:

machine: ~> set home = /
machine: / home / user> cd
machine: ~> unset home
Maschine: /> CD
cd: Kein Heimatverzeichnis
Maschine: /> 

Sie haben die falsche Variable gelöscht. Es handelt sich nicht um HOMEdie Umgebungsvariable, sondern um homedie interne Variable der C-Shell (die beim Starten der Shell anhand des Werts der vorherigen Variable initialisiert wird, ansonsten jedoch um eine eigenständige Variable).

JdeBP
quelle
no on csh (zumindest in meiner Version: "tcsh 6.18.01 (Astron) 2012-02-14 (x86_64-apple-darwin)") ist die Variable HOME, die den Wert von home enthält. Aber wie @Stephane Chazelas sagte, muss ich die Variable vor dem Starten der Shell deaktivieren, da sie beim Start den HOME-Wert setzt.
LotoLo
Das obige ist die C-Shell, die ich auf einer handlichen OpenBSD-Maschine ausgeführt habe und die ihr Verhalten demonstriert. Es ist nicht einmal die TENEX C-Shell (auch wenn sich das so verhält).
JdeBP
Ja, ich habe es gesehen ... Ich habe getippt, cshaber anscheinend ist es auftcsh
LotoLo
0

Das System hat die Variable HOME zum Zeitpunkt der Anmeldung auf einen Pfadnamen des Basisverzeichnisses des Benutzers festgelegt. Es wird eingestellt von

  • gdm, kdm oder xdm für grafische sitzungen.
  • Melden Sie sich in Konsolen-, Telnet- und Rlogin-Sitzungen an
  • sshd für SSH-Verbindungen

Sie können den Wert ändern, aber achten Sie darauf, dass .bashrc, .profile, .xinitrc usw. nicht gelesen werden, wenn sie sich nicht im Ausgangsverzeichnis befinden.

Dababi
quelle
Aber ich kann es deaktivieren ($ HOME) ... richtig? Und woher weiß es, wo ein anderer Benutzer zu Hause ist?
LotoLo
1
Sie können es mit dem usermod -d HOME_DIRBefehl aktualisieren , wenn ein neuer Benutzer erstellt wird. Das Standard-Home ist / home / $ username und wird vom Anmeldeprogramm festgelegt.
Dababi