Como um shell conhece o (s) home (s)?

24

Cada shell tem uma variável de ambiente $ HOME set (ex: /Users/lotolo ). Se estou sob csh posso unsetenv HOME e ainda se eu fizer cd estarei em minha casa. Eu testei isso também no bash ( unset HOME ) e é o mesmo comportamento. Então, como o shell sabe onde está minha / other_user home? Onde lê esses valores?

Esta não é uma duplicata, pois a minha pergunta não é como eu sei, mas como o shell sabe HOME . E esse comportamento também é estendido a outros usuários.

    
por LotoLo 28.11.2016 / 16:35

3 respostas

33

No caso de csh e tcsh , ele registra o valor da variável $HOME no momento em que o shell foi iniciado ( em sua variável $home como observado por @JdeBP ).

Se você desativá-lo antes de iniciar o csh , verá algo como:

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

Para bash (e a maioria dos outros tipos de Bourne), vejo um comportamento diferente do seu.

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

O conteúdo da variável $HOME é inicializado pelo processo de login com base nas informações armazenadas no banco de dados do usuário em relação ao seu usuário nome .

As informações sobre o nome do usuário nem sempre estão disponíveis. Tudo o que um shell pode ter certeza é o userid do processo que o está executando e vários usuários (com diferentes diretórios home) podem compartilhar o mesmo userid.

Portanto, uma vez que $HOME tenha desaparecido, não há uma maneira confiável de recuperá-lo.

Consultar o banco de dados do usuário (com getpwxxx() API padrão) para o diretório inicial do primeiro usuário que possui o mesmo uid daquele que está executando o shell seria apenas uma aproximação (sem mencionar o fato de que o banco de dados do usuário poderia foram alteradas (ou o diretório inicial sendo definido como um valor único) desde o início da sessão de login).

zsh é o único shell que eu conheço que faz isso:

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

Todos os outros shells que eu tentei reclamam do unset HOME ou usam / como valor inicial padrão.

No entanto, um comportamento diferente é fish , o que parece consultar o banco de dados para o nome de usuário armazenado em $USER , se houver, ou fazer um getpwuid() , se não:

$ 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 quando o usuário não existe ( link ):

$ env -u HOME USER=foo fish -c ''
zsh: segmentation fault  env -u HOME USER=foo fish -c ''
    
por 28.11.2016 / 16:55
6

So how does the shell know where is my/other_user home?

Isso não acontece. Você simplesmente não está realizando o experimento corretamente. Como você pode ver no manual do shell C, o comando cd é alterado para o valor da variável home se fornecido sem argumentos. Se esta variável não estiver definida, não sabe para onde mudar o diretório e imprime um erro:

machine:~> set home=/
machine:/home/user> cd
machine:~> unset home
machine:/> cd
cd: No home directory
machine:/> 

Você não ajustou a variável errada. Não é HOME , a variável de ambiente, é home a variável interna do shell C (inicializada a partir do valor do primeiro quando o shell é iniciado, mas de outra forma uma variável independente em si).

    
por 28.11.2016 / 16:58
0

O sistema configurou a variável HOME no momento do login para ser um nome de caminho do diretório pessoal do usuário. É definido por

  • gdm, kdm ou xdm para sessões gráficas.
  • faça o login nas sessões de console, telnet e rlogin
  • sshd para conexões SSH

Você pode alterar seu valor, mas preste atenção, pois .bashrc, .profile, .xinitrc, etc não serão lidos se não estiverem no diretório inicial.

    
por 28.11.2016 / 16:53