Comment obtenir HOME, USER donné?

41

J'ai une USERvariable dans mon script et je veux voir son HOMEchemin basé sur la USERvariable. Comment puis je faire ça?

MatthewRock
la source

Réponses:

73

Il existe un utilitaire qui recherche les informations utilisateur indépendamment du fait que ces informations soient stockées dans des fichiers locaux tels que /etc/passwdou dans LDAP ou une autre méthode. Ça s'appelle getent.

Pour en extraire les informations utilisateur, vous exécutez getent passwd $USER. Vous obtiendrez une ligne qui ressemble à ceci:

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

Maintenant, vous pouvez simplement en couper le répertoire home, par exemple en utilisant cut, comme suit:

[jenny@sameen ~]$ getent passwd jenny | cut -d: -f6
/home/jenny
Jenny D
la source
getent est la meilleure solution, spécialement pour les utilisateurs distants. dans des systèmes plus simples, ~ utilisateur devrait suffire. Modded vous up.
Rui F Ribeiro
@RuiFRibeiro, vous ne pouvez pas utiliser ~fooavec des variables dans bash. Pas directement, de toute façon.
muru
1
@muru - c'est vrai - et c'est un comportement spécifique. Il ~semble cependant que l'onglet semble se développer et qu'un autre comportement spécifié du préfixe tilde doit être remplacé par un chemin d'accès du répertoire de travail initial associé au nom de connexion obtenu à l'aide de la getpwnam()fonction . Cette recherche est donc probablement très bonne. Je n'aime pas les extensions de tabulation, cependant - j'aime taper des tabulations.
mikeserv
1
Notez que cela ne vous donne que la valeur initiale de $ HOME; Les scripts de connexion de l'utilisateur sont parfaitement habilités à le changer. C'est une chose inhabituelle à faire, mais je peux penser à des situations où il serait judicieux, par exemple de choisir entre un homedir local et un homedir monté sur NFS.
Déc
1
@HagenvonEitzen Les deux points sont interdits précisément parce qu'ils ont été utilisés pour séparer des champs.
Jenny D
9

Vous pouvez utiliser evalpour obtenir le répertoire personnel de quelqu'un.

eval echo "~$USER"

Au moins pour les utilisateurs locaux, cela fonctionne à coup sûr. Je ne sais pas si les utilisateurs distants comme LDAP sont gérés eval.

Sarolf.Thorleif
la source
1
Pas besoin d'eval ici. Soyez prudent avec votre anglais.
Rui F Ribeiro
4
@nwk un evalest nécessaire. Bash ne traite pas ~fooaprès une expansion variable.
muru
1
Intéressant, merci, mais cela ne récupère que le répertoire de l' utilisateur actuel , pas celui des autres utilisateurs. Je pense que les utilisateurs LDAP ne sont pas gérés, bien que je puisse me tromper.
Rui F Ribeiro
3
@RuiFRibeiro Cela fonctionnera bien avec LDAP, utilisez simplement la variable contenant le nom d'utilisateur de votre utilisateur LDAP au lieu de USER.
Muru
3
Ne pas utiliser ce sans vérifier que se $USERdéveloppe pour juste une seule chaîne de caractères alphabétiques.
Chepner
4

La place habituelle est /home/$USER, mais cela ne doit pas nécessairement être universel. Le lieu définitif pour rechercher de telles informations se trouve dans le fichier /etc/passwd.

Ce fichier est lisible dans le monde entier (tout le monde peut le lire), ainsi tout utilisateur a accès à son contenu.
Si $ USER existe dans le fichier, l'entrée précédente est le répertoire HOME de l'utilisateur.

Ceci sélectionnera l’entrée et imprimera le répertoire HOME:

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

Pour les systèmes plus complexes (distants), getent est la commande habituelle pour obtenir des informations sur les utilisateurs à partir du système NSS (Name Service Switch libraries).

Une commande de

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

Fournira des informations équivalentes (si disponibles).


la source
2
vous avez ~ utilisateur pour cela, et votre solution ne considère pas les utilisateurs dans des systèmes plus complexes, comme les utilisateurs provenant de LDAP où vous devez utiliser getent.
Rui F Ribeiro
2

Si l'utilisateur n'existe pas, getentune erreur sera renvoyée.

Voici une petite fonction shell qui n'ignore pas le code de sortie de getent:

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

Voici un exemple d'utilisation:

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
la source
1

Si vous êtes connecté en tant qu'utilisateur root, si vous connaissez USERle mot de passe ou s'il USERn'y en a pas, l'option suivante est une autre option:

    su -c 'echo ~' ${USER}

Sous le sucomportement standard , s'il USERest non défini ou vide, il sutentera alors d'exécuter la commande en tant que root.

Si la valeur USERest pas un nom d'utilisateur valide, une erreur appropriée sera soulevée: su: user <user> does not exist.

Il y a déjà beaucoup de bonnes réponses ici, mais cela peut toujours aider quelqu'un.

monotone
la source
Ce n'est pas sécurisé, cela dépend de la configuration du système. Il exécute un processus (le shell qui exécute echo) en tant qu'utilisateur. Ainsi, l'utilisateur peut (par exemple) extraire le shell et vous donner une sortie arbitraire. Il est également exécuté dans la configuration de l'utilisateur. Il est donc possible que les fichiers de configuration du shell de l'utilisateur soient exécutés (ce qui peut également donner des résultats arbitraires). Ou des charges d'environnement via pam. Etc. Ou faites simplement quelque chose d'aussi simple que d'envoyer un SIGSTOP pour qu'il dure longtemps, efficacement, en attaquant votre script sous DOS.
derobert le