¿Cómo llegar a CASA, dado USUARIO?

41

Tengo una USERvariable en mi script y quiero ver su HOMEruta en función de la USERvariable. ¿Cómo puedo hacer eso?

MatthewRock
fuente

Respuestas:

73

Hay una utilidad que buscará información del usuario independientemente de si esa información se almacena en archivos locales como /etc/passwdLDAP o algún otro método. Se llama getent.

Para obtener información del usuario, ejecuta getent passwd $USER. Obtendrá una línea de regreso que se ve así:

[jenny@sameen ~]$ getent passwd jenny
jenny:*:1001:1001:Jenny Dybedahl:/home/jenny:/usr/local/bin/bash

Ahora puede simplemente cortar el directorio de inicio, por ejemplo, usando cut, así:

[jenny@sameen ~]$ getent passwd jenny | cut -d: -f6
/home/jenny
Jenny D
fuente
getent es la mejor respuesta, especialmente con usuarios remotos. en sistemas más simples ~ el usuario debería ser suficiente. Te modificó.
Rui F Ribeiro
@RuiFRibeiro no se puede usar ~foocon variables bash. No directamente, de todos modos.
muru
1
@muru, eso es cierto, y es un comportamiento específico. Sin ~embargo, parece expandirse por tabulación, y otro comportamiento especificado del prefijo tilde se reemplazará por un nombre de ruta del directorio de trabajo inicial asociado con el nombre de inicio de sesión obtenido utilizando la getpwnam()función y, por lo tanto, probablemente esa búsqueda sea bastante buena. Sin embargo, no me gustan las expansiones de pestañas, me gusta escribir pestañas.
mikeserv
1
Tenga en cuenta que esto solo le da el valor inicial de $ HOME; los scripts de inicio de sesión del usuario tienen el derecho perfecto de cambiarlo a otra cosa. Es algo inusual, pero puedo pensar en situaciones en las que sería sensato, por ejemplo, elegir entre un homedir local y uno montado en NFS.
zwol
1
@HagenvonEitzen Colones están prohibidos precisamente porque se han utilizado para separar campos.
Jenny D
9

Puede usar evalpara obtener el directorio personal de alguien.

eval echo "~$USER"

Al menos para los usuarios locales, esto funciona con seguridad. No sé si se manejan usuarios remotos como LDAP eval.

Sarolf.Thorleif
fuente
1
No hay necesidad de evaluar allí. Ten cuidado con tu inglés.
Rui F Ribeiro
44
evalSe necesita @nwk an . Bash no se procesa ~foodespués de la expansión variable.
muru
1
Interesante, gracias, sin embargo, esto solo obtiene el directorio del usuario actual , no de otros usuarios. Creo que los usuarios de LDAP no se manejan, aunque puedo estar equivocado.
Rui F Ribeiro
3
@RuiFRibeiro Funcionará bien con LDAP, solo use cualquier variable que contenga el nombre de usuario de su usuario LDAP en lugar de USER.
muru
3
No utilice este sin verificar que $USERse expande a solo una única cadena de caracteres alfabéticos.
chepner
4

El lugar habitual es /home/$USER, pero eso no tiene que ser universal. El lugar definitivo para buscar dicha información es dentro del archivo /etc/passwd.

Ese archivo es legible en todo el mundo (cualquiera podría leerlo), por lo que cualquier usuario tiene acceso a su contenido.
Si el $ USER existe en el archivo, la entrada anterior al último es el directorio HOME del usuario.

Esto seleccionará la entrada e imprimirá el directorio HOME:

awk -v FS=':' -v user="$USER" '($1==user) {print $6}' "/etc/passwd"

Para sistemas más complejos (remotos), getent es el comando habitual para obtener información de los usuarios del sistema NSS (bibliotecas de cambio de servicio de nombres).

Un comando de

echo $(getent passwd $USER )| cut -d : -f 6

Proporcionará información equivalente (si está disponible).


fuente
2
tiene ~ usuario para eso, y su solución no contempla usuarios en sistemas más complejos, como el usuario que viene de LDAP donde tiene que usar getent.
Rui F Ribeiro
2

Si el usuario no existe, getentdevolverá un error.

Aquí hay una pequeña función de shell que no ignora el código de salida de getent:

get_home() {
  local result; result="$(getent passwd "$1")" || return
  echo $result | cut -d : -f 6
}

Aquí hay un ejemplo de uso:

da_home="$(get_home missing_user)" || {
  echo 'User does NOT exist!'; exit 1
}

# Now do something with $da_home
echo "Home directory is: '$da_home'"
Elifarley
fuente
1

Si ha iniciado sesión como root, si conoce USERla contraseña o si USERno tiene contraseña, la siguiente es otra opción:

    su -c 'echo ~' ${USER}

Bajo el sucomportamiento estándar , si USERno está definido o está vacío, suintentará ejecutar el comando como root.

Si el valor de USERno es un nombre de usuario válido, entonces se produce un error apropiado: su: user <user> does not exist.

Ya hay muchas buenas respuestas aquí, pero esto puede ayudar a alguien.

monótono
fuente
Esto no es seguro, dependiendo de la configuración del sistema. Ejecuta un proceso (el shell ejecuta echo) como ese usuario, por lo que el usuario podría (por ejemplo) trazar el shell y darle resultados arbitrarios. También se ejecuta en la configuración del usuario, por lo que es posible que se ejecuten los archivos de configuración de shell de los usuarios (lo que también podría dar resultados arbitrarios). O el medio ambiente se carga a través de pam. Etc. O simplemente haga algo tan simple como enviarle un SIGSTOP para que tome una eternidad, atacando efectivamente su script DOS.
derobert