¿Quién establece las variables de entorno $ USER y $ USERNAME?

34

Además, ¿estas variables siempre coincidirán con el nombre de usuario actualmente conectado (lo hacen en mi sistema Debian)? ¿Puedo asumir su disponibilidad en otros sistemas Unix (similares)?

También tengo curiosidad de por qué uno usaría en whoamilugar de simplemente leer cualquiera de estas variables.

tshepang
fuente
2
Mirando la manpágina, whoamiinforma el nombre asociado con su identificación de usuario efectiva. Lo que significa que devolverá algo diferente si está utilizando sudoo ejecutando un ejecutable setuid. Si ha sudoconfigurado, intente sudo whoamipor ejemplo.
Joseph R.
44
USERy USERNAMEson variables de entorno ordinarias, lo que significa que, si lo desea, puede establecerlas en valores arbitrarios. Solo escribe USER=xyz. En otras palabras, incluso si esas variables existen, no hay garantía de que sus valores coincidan con el nombre de usuario actualmente conectado.
Uwe
@Uwe By guarantee, quise decir por defecto (es decir, suponiendo que el usuario no los cambió).
tshepang
2
@Tshepang Como seguimiento de mi primer comentario: compare los resultados de sudo whoamiysudo echo $USER
Joseph R.
2
@JosephR. Para sudo echo $USER, el shell se expande $USER, luego llama sudo. Por supuesto, no produce el mismo resultado que whoami. Como sudo whoami, sudo sh -c 'echo $USER'hace (típicamente) salida root. Con respecto a su comentario sobre el whoamiuso del EUID , tenga en cuenta que sudo whoamise generarároot incluso si se whoamiusa el UID. sudoestablece tanto EUID como UID para el comando que ejecuta (excepto en la situación muy inusual en la que lo configura explícitamente para que se comporte de otra manera). Comparar sudo id -ua sudo id -ru.
Eliah Kagan

Respuestas:

29

Es iniciar sesión .

La página de manual de inicio de sesión de Linux (1) dice:

El valor de $ HOME , $ USER , $ SHELL , $ PATH , $ LOGNAME y $ MAIL se establece de acuerdo con los campos apropiados en la entrada de la contraseña.

La página de manual de inicio de sesión de FreeBSD (1) dice:

La utilidad de inicio de sesión ingresa información en el entorno (consulte el entorno ( 7) ) especificando el directorio de inicio del usuario (HOME), el intérprete de comandos (SHELL), la ruta de búsqueda (PATH), el tipo de terminal (TERM) y el nombre de usuario (LOGNAME y USER) .

Las páginas de manual de NetBSD , OpenBSD y OS X dicen lo mismo.

Aquí está el código fuente del inicio de sesión 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);

Aquí está el código fuente del inicio de sesión de FreeBSD:

(void)setenv("LOGNAME", username, 1);
(void)setenv("USER", username, 1);
(void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);
poige
fuente
2
En mi caja de Fedora 16, tengo tanto USERy USERNAMEset y su comando sólo devuelve LOGNAME.
Joseph R.
1
. @JosephR, por desgracia no tengo Fedora en las manos, pero He mirado en las fuentes de FreeBSD, así, ver UPD ..
poige
Pero esto no es obviamente el caso en Fedora. Todo lo que estoy diciendo es, loginno parece ser el único establecimiento de estas variables.
de Joseph R.
1
Tenga en cuenta que Linux es sólo un núcleo, que no tiene un logincomando. Sistemas operativos que utilizan Linux como su núcleo son libres de usar cualquier aplicación que les gusta. Por ejemplo sistemas basados en Debian tienden a usar el de shadow-utils, no util-linux.
Stéphane Chazelas
1
Tenga en cuenta que loginmuchas veces no se invoca al iniciar sesión en más ssho por la mayoría de los administradores de inicio de sesión gráfica.
Stéphane Chazelas
11

No hay ninguna regla. Algunas conchas gusta tcsho zshconjunto $LOGNAME. zshconjuntos $USER.

Puede ser ajustado por algunas cosas que inicie sesión en perfectas login(como invocada por gettymomento de la conexión en un terminal y, a veces por otras cosas como in.rlogind), cron, su, sudo, sshd, rshd, los administradores de inicio de sesión gráfica o no.

Sin embargo, si ha habido un inicio de sesión, en mi experiencia, $USERgeneralmente se establece (pero no se puede actualizar después de un cambio de identificación de usuario (a través de comandos setuid) dentro de esa sesión de inicio de sesión. POSIX requiere que $LOGNAMEse establezca al iniciar sesión (y cron).

Para obtener el nombre de inicio de sesión de forma portátil, mejor es utilizar el lognamecomando (si no ha habido ninguna entrada, puede devolver nada). Para obtener el identificador de usuario, utilice id -u. Para obtener un nombre de usuario correspondiente a la corriente id de usuario: id -un. Para obtenerlos todos (la mayoría de las veces, solo hay un nombre de usuario por ID de usuario, pero eso no está garantizado):

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

Aunque eso puede no funcionar en sistemas donde la base de datos de usuarios no se puede enumerar (como sucede a veces con las bases de datos de usuarios en red, por ejemplo).

Stéphane Chazelas
fuente
3

Probablemente desee confiar en el estándar POSIX aquí, ya que en algún momento probablemente le interesará no solo el inicio de sesión de usuario (administrado por el loginprograma) sino también crontrabajos y similares.

Por lo tanto, debe saber que POSIX requiere $LOGNAMEpero no $USER. Por ejemplo $USER, no puede establecerlo cron, como se señala en una respuesta de Keith Thompson , que también hace referencia a algunos antecedentes sobre cómo esto se relaciona con la historia de System-V vs BSD:

... al menos en mi sistema (Ubuntu 14.04) la variable de entorno $ USER no está configurada para trabajos cron. En su lugar, puede usar $ LOGNAME, que es parte del entorno para trabajos cron.

De acuerdo con la página de comando man ambient (7) (escriba man Bols para leerlo), $ USER es utilizado por programas derivados de BSD y $ LOGNAME es utilizado por programas derivados de System-V.

nealmcb
fuente
1

Si desea utilizar las variables de entorno (en lugar de whoamio getpwenty getpwnam) y no está seguro de si siempre se configuran de la misma manera en todos los sistemas * NIX, intente esto en bash:

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

Si todavía está vacío después de todo eso, entonces estás en un sistema bastante esotérico. ;)

Jesse Chisholm
fuente