web-dev-qa-db-fra.com

Qui définit les variables d'environnement $ USER et $ USERNAME?

De plus, ces variables correspondront-elles toujours au nom d'utilisateur actuellement connecté (comme c'est le cas sur mon système Debian)? Puis-je supposer leur disponibilité dans d'autres systèmes Unix (similaires)?

Je suis également curieux de savoir pourquoi on utiliserait whoami au lieu de simplement lire l'une de ces variables.

37
tshepang

C'est la connexion .

La page de manuel Linux login (1) dit:

La valeur de $ HOME , $ USER , $ Shell , $ PATH , $ LOGNAME et $ MAIL sont définis en fonction des champs appropriés dans la saisie du mot de passe.

La page de manuel FreeBSD login (1) dit:

L'utilitaire de connexion saisit les informations dans l'environnement (voir environ (7) ) spécifiant le répertoire personnel de l'utilisateur (HOME), commande interprète (Shell), chemin de recherche (PATH), type de terminal (TERM) et nom d'utilisateur (LOGNAME et USER).

Les pages de manuel NetBSD , OpenBSD et OS X disent la même chose.

Voici le code source de la connexion util-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);

Voici le code source de la connexion FreeBSD:

(void)setenv("LOGNAME", username, 1);
(void)setenv("USER", username, 1);
(void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);
31
poige

Il n'y a pas de règle. Certains shells comme tcsh ou zsh set $LOGNAME. zsh définit $USER.

Il peut être défini par certaines choses qui vous connectent comme login (comme invoqué par getty lors de la connexion sur un terminal et parfois par d'autres choses comme in.rlogind), cron, su, Sudo, sshd, rshd, les gestionnaires de connexion graphiques ou non.

S'il y a eu une connexion, d'après mon expérience, $USER est généralement défini (mais il ne peut pas être mis à jour après un changement d'ID utilisateur (via les commandes setuid) au cours de cette session de connexion. POSIX requiert que $LOGNAME être défini lors de la connexion (et cron).

Pour obtenir le nom de connexion de manière portable, le mieux est d'utiliser la commande logname (s'il n'y a pas eu de connexion, il ne peut rien retourner). Pour obtenir l'ID utilisateur, utilisez id -u. Pour obtenir un nom d'utilisateur correspondant à l'ID utilisateur effectif actuel: id -un. Pour les obtenir tous (la plupart du temps, il n'y a qu'un seul nom d'utilisateur par ID utilisateur, mais ce n'est pas garanti):

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

Bien que cela puisse ne pas fonctionner sur les systèmes où la base de données utilisateur ne peut pas être énumérée (comme cela arrive parfois avec les bases de données utilisateur en réseau par exemple).

12

Si vous souhaitez utiliser les variables d'environnement (au lieu de whoami ou getpwent et getpwnam) et que vous ne savez pas si elles sont toujours définies de la même manière sur tous les systèmes * NIX, puis essayez ceci dans bash:

THIS_USER=${USER:-${USERNAME:-${LOGNAME}}}
echo ${THIS_USER}

S'il est toujours vide après tout cela, alors vous êtes sur un système plutôt ésotérique. ;)

3
Jesse Chisholm

Vous voudrez probablement vous fier à la norme POSIX ici, car à un moment donné, vous vous soucierez probablement non seulement de la connexion utilisateur (gérée par le login program) mais aussi cron jobs et similaires.

Par conséquent, vous devez savoir que POSIX nécessite $LOGNAME mais non $USER. Par exemple. $USER ne peut pas être défini par cron, comme indiqué dans un réponse de Keith Thompson , qui fait également référence à un historique sur la façon dont cela se rapporte à l'histoire de System-V vs BSD:

... au moins sur mon système (Ubuntu 14.04), la variable d'environnement $ USER n'est pas définie pour les tâches cron. À la place, vous pouvez utiliser $ LOGNAME, qui fait partie de l'environnement pour les tâches cron.

Selon la page de manuel environ (7) (tapez man environ pour le lire), $ USER est utilisé par les programmes dérivés de BSD et $ LOGNAME est utilisé par les programmes dérivés de System-V.

3
nealmcb