Quem define as variáveis de ambiente $ USER e $ USERNAME?

30

Além disso, essas variáveis sempre corresponderão ao nome de usuário registrado no momento (elas fazem no meu sistema Debian)? Posso assumir a disponibilidade deles em outros sistemas Unix (similares)?

Também estou curioso para saber por que alguém usaria whoami em vez de apenas ler qualquer uma dessas variáveis.

    
por Tshepang 19.05.2013 / 13:31

3 respostas

22

É login .

A página man do login (1) do Linux diz:

The value for $HOME, $USER, $SHELL, $PATH, $LOGNAME, and $MAIL are set according to the appropriate fields in the password entry.

A página do login (1) do FreeBSD diz:

The login utility enters information into the environment (see environ(7)) specifying the user's home directory (HOME), command interpreter (SHELL), search path (PATH), terminal type (TERM) and user name (both LOGNAME and USER).

O NetBSD , OpenBSD e OS X dizem a mesma coisa.

Aqui está o código-fonte do util login -linux:

setenv("HOME", pwd->pw_dir, 0); /* legal to override */
setenv("USER", pwd->pw_name, 1);
setenv("SHELL", pwd->pw_shell, 1);
/* ... */
setenv("LOGNAME", pwd->pw_name, 1);

Veja a fonte código do login do FreeBSD:

(void)setenv("LOGNAME", username, 1);
(void)setenv("USER", username, 1);
(void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);
    
por 19.05.2013 / 13:41
9

Não há regra. Algumas conchas como tcsh ou zsh set $LOGNAME . zsh conjuntos $USER .

Pode ser definido por alguns itens que fazem login como login (como invocado por getty quando o login em um terminal e às vezes por outras coisas como in.rlogind ), cron , su , sudo , sshd , rshd , gerenciadores de login gráficos ou não.

Se houver um login, na minha experiência, $USER é geralmente definido (mas pode não ser atualizado depois de uma mudança de id de usuário (via comandos setuid) dentro daquela sessão de login. POSIX requer que $LOGNAME seja definido no login (e cron ).

Para obter o nome de login portavelmente, o melhor é usar o comando logname (se não houver nenhum login, ele poderá retornar nada). Para obter o ID do usuário, use id -u . Para obter um nome de usuário correspondente ao ID do usuário efetivo atual: id -un . Para obter todos eles (na maioria das vezes, há apenas um nome de usuário por ID de usuário, mas isso não é garantido):

perl -le 'while ($n = getpwent()) {print $n if getpwnam($n) == $>}'

Embora isso não funcione em sistemas em que o banco de dados do usuário não pode ser enumerado (como acontece às vezes com bancos de dados de usuários em rede, por exemplo).

    
por 19.05.2013 / 15:57
2

Você provavelmente vai querer contar com o padrão POSIX aqui, já que em algum momento você provavelmente se importará em não apenas login de usuário (gerenciado pelo programa login ), mas também cron jobs e afins.

Portanto, você deve saber que o POSIX requer $LOGNAME , mas não $USER . Por exemplo. $USER pode não ser definido pelo cron, como apontado em uma resposta de Keith Thompson , que também faz referência a um histórico sobre como isso se relaciona com a história do System-V vs BSD:

... at least on my system (Ubuntu 14.04) the $USER environment variable is not set for cron jobs. Instead, you can use $LOGNAME, which is part of the environment for cron jobs.

According to the environ(7) man page (type man environ to read it), $USER is used by BSD-derived programs and $LOGNAME is used by System-V-derived programs.

    
por 04.11.2017 / 17:16