¿Cómo conoce una casa un hogar?

25

Cada shell tiene una variable de entorno $ HOME set (ej /Users/lotolo.:). Si estoy bajo csh puedo unsetenv HOMEy aún si lo hago cd, estaré en mi casa. He probado esto también en bash ( unset HOME) y es el mismo comportamiento. Entonces, ¿cómo sabe el shell dónde está mi / other_user home? ¿Dónde lee esos valores?

Esto no es un duplicado desde que mi pregunta no es ¿cómo lo sé, pero ¿cómo lo hace la cáscara conocimientos HOME. Y este comportamiento también se extiende a otros usuarios.

LotoLo
fuente
1
@StephenKitt, no, no es un duplicado. Aquí estamos hablando del comportamiento del shell para el directorio de inicio del usuario actual.
Stéphane Chazelas
En el caso simple de /etc/passwd. Algunos sistemas pueden almacenar esa información en LDAP, servidores NIS, etc.
Satō Katsura
1
Los programas (incluidos los shells) simplemente llaman getpwuid(3)o son similares Algunos sistemas se pueden configurar para "redirigir" getpwuid(3)para recuperar información de /etc/passwd, LDAP, NIS, NIS + etc.
Satō Katsura
@StephenKitt, mira mi respuesta
Stéphane Chazelas
1
@ GAD3R, vea la discusión anterior, StephenKitt ya había señalado ese mismo duplicado (que él retiró desde entonces), pero yo argumento arriba (y veo también mi respuesta) que no es un duplicado.
Stéphane Chazelas

Respuestas:

33

En el caso de cshy tcsh, registra el valor de la $HOMEvariable en el momento en que se inició el shell ( en su $homevariable como lo señaló @JdeBP ).

Si lo desarma antes de comenzar csh, verá algo como:

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

Para bash(y la mayoría de los otros shells tipo Bourne), veo un comportamiento diferente al tuyo.

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

El contenido de la $HOMEvariable se inicializa mediante el proceso de inicio de sesión en función de la información almacenada en la base de datos de usuario con su nombre de usuario .

La información sobre el nombre de usuario en sí no siempre está disponible. Todo lo que un shell puede saber con certeza es el ID de usuario del proceso que lo está ejecutando y varios usuarios (con diferentes directorios de inicio) pueden compartir el mismo ID de usuario.

Entonces, una vez que $HOMEse va, no hay una forma confiable de recuperarlo.

Consultar la base de datos de usuario (con getpwxxx()API estándar) para el directorio de inicio del primer usuario que tiene el mismo uid que el que ejecuta el shell solo sería una aproximación (sin mencionar el hecho de que la base de datos de usuario podría haber cambiado (o el inicio el directorio se define como un valor único) desde que comenzó la sesión de inicio de sesión).

zsh es el único shell que sé que hace eso:

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

Todos los otros proyectiles que probé se quejan de que HOME no está configurado o lo usan /como valor de inicio predeterminado.

Sin embargo, un comportamiento diferente es fishel que parece consultar en la base de datos el nombre de usuario almacenado en $USERcaso de existir o hacer un getpwuid()caso en caso contrario:

$ 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 cuando el usuario no existe ( 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
fuente
2
¡Supongo que podemos informar este problema! Muy buena respuesta por cierto, gracias!
LotoLo
1
@LotoLo, sí, estoy ocupado construyendo con fishla cabeza del desarrollador para ver si el error también está allí. Editar. Sí lo es.
Stéphane Chazelas
Ahora tengo curiosidad: ¿qué variable de entorno hace que el shell sea más amigable para el usuario si no está configurado? PATH? TERM? USER?
user1024
Aquí hay una línea extraña: "solo sería una aproximación ..." Los paréntesis tampoco se alinean en ese párrafo. ¿Qué se suponía que era?
muru
1
@muru Querying the user database... would only be...no está tan claro de hecho
edc65
6

Entonces, ¿cómo sabe el shell dónde está mi / other_user home?

No lo hace. Simplemente no estás realizando el experimento correctamente. Como puede ver en el manual del shell C, el cdcomando cambia al valor de la homevariable si no se proporciona ningún argumento. Si esta variable no está configurada, no sabe a dónde cambiar el directorio e imprime un error:

máquina: ~> set home = /
máquina: / inicio / usuario> cd
máquina: ~> desarmar inicio
máquina: /> cd
cd: sin directorio de inicio
máquina: /> 

Desarmaste la variable incorrecta. No es HOME, la variable de entorno, es homela variable interna de la shell C (inicializada a partir del valor de la primera cuando se inicia la shell, sino una variable independiente por derecho propio).

JdeBP
fuente
no en csh (al menos en mi versión: "tcsh 6.18.01 (Astron) 2012-02-14 (x86_64-apple-darwin)") es la variable HOME que lleva el valor de la casa. Pero como dijo @Stephane Chazelas, debo desarmar la variable antes de iniciar el shell, ya que establecerá el valor HOME al inicio.
LotoLo
Lo anterior es el shell C, que ejecuté en una práctica máquina OpenBSD, y demuestra su comportamiento. Ni siquiera es el shell TENEX C (aunque eso se comporta igual).
JdeBP
Sí, lo vi ... escribí cshpero aparentemente tiene un aliastcsh
LotoLo
0

El sistema establece la variable INICIO al momento de iniciar sesión para que sea una ruta de acceso del directorio de inicio del usuario. Es establecido por

  • gdm, kdm o xdm para sesiones gráficas.
  • iniciar sesión en la consola, telnet y sesiones de registro
  • sshd para conexiones SSH

Puede cambiar su valor pero preste atención porque .bashrc, .profile, .xinitrc, etc. no se leerán si no están en el directorio de inicio.

Dababi
fuente
Pero puedo desarmarlo ($ HOME) ... ¿verdad? ¿Y cómo sabe dónde está la casa de otro usuario?
LotoLo
1
puede actualizarlo usando el usermod -d HOME_DIRcomando, cuando se crea un nuevo usre. el inicio predeterminado es / home / $ username y lo determina el programa de inicio de sesión.
Dababi