Comment obtenir le répertoire $HOME de l'utilisateur différent dans le script bash?
J'ai besoin pour l'exécution d'une partie d'un script bash en tant qu'utilisateur différent, et à l'intérieur de cet utilisateur $HOME
répertoire. Cependant, je ne suis pas sûr de la façon de déterminer cette variable. Commutation de l'utilisateur et de l'appel de $HOME
ne fournit pas à l'emplacement correct:
# running script as root, but switching to a different user...
su - $different_user
echo $HOME
# returns /root/but should be /home/myuser
Mise à jour:
Il semble que le problème est avec la manière que je suis en train de changer d'utilisateur dans mon script:
$different_user=deploy
# create user
useradd -m -s /bin/bash $different_user
echo "Current user: `whoami`"
# Current user: root
echo "Switching user to $different_user"
# Switching user to deploy
su - $different_user
echo "Current user: `whoami`"
# Current user: root
echo "Current user: `id`"
# Current user: uid=0(root) gid=0(root) groups=0(root)
sudo su $different_user
# Current user: root
# Current user: uid=0(root) gid=0(root) groups=0(root)
Quelle est la bonne façon de passer les utilisateurs et exécuter des commandes en tant qu'utilisateur différent dans un script bash?
- Vous pouvez toujours extraire à partir de /etc/passwd, en supposant qu'elle est définie localement compte.
su - $different_user
doit avoir été suffisante. Êtes-vous sûr que vous êtes encore connecté en tant quemyuser
. Essayez d'exécuterid
commande pour vérifier. Certains shell de connexion est défini surnologin
et il sort dès que vous vous connectez en tant quemyuser
.- J'ai mis à jour ma question d'inclure la façon dont j'ai créé l'utilisateur. Essentiellement:
useradd -m -s /bin/bash $different_user
. - Merci de prendre un autre regard sur ma réponse. Je substantiellement modifié pour qu'il corresponde exactement à ce que vous avez essayé de le faire.
Vous devez vous connecter pour publier un commentaire.
Mise à jour: Basé sur cette question du titre, les gens semblent venir ici simplement à la recherche d'un moyen de trouver un autre répertoire home de l'utilisateur, sans avoir besoin de usurper l'identité d' que l'utilisateur.
Dans ce cas, la solution la plus simple est d'utiliser tilde expansion avec le nom d'utilisateur de l'intérêt, combinée avec
eval
(ce qui est nécessaire, parce que le nom d'utilisateur doit être donné comme un non cotées littérale pour tilde expansion au travail):Remarque: Le d'habitude mises en garde concernant l'utilisation de
eval
appliquer; dans ce cas, l'hypothèse est que vous pouvez contrôler la valeur de$different_user
et savent que c'est un simple nom d'utilisateur.En revanche, le reste de cette réponse traite usurpation de l'identité d' un utilisateur et de l'exécution d'opérations dans ce répertoire home de l'utilisateur.
Remarque:
sudoers
fichier peut usurper l'identité d'autres utilisateurs viasudo
.sudo
- modification de sa configuration peut la faire se comporter différemment - voirman sudoers
.La forme de base de l'exécution d'une commande en tant qu'un autre utilisateur est:
Remarque:
-H
, l'usurpation de l'identité d'processus (le processus invoqué dans le contexte de l'utilisateur spécifié) de déclarer la original répertoire home de l'utilisateur dans$HOME
.someExe
arrive à être un shell) - les expansions par le invoquant shell - avant de passer à l'usurpation de l'identité d'processus peut évidemment se produisent encore.En option, vous pouvez disposer d'une usurpation de l'identité d'processus exécuter ou par l'intermédiaire d'un(n usurpation de l'identité d') shell, en préfixant
someExe
soit avec-i
ou-s
- ne pas spécifiersomeExe ...
crée un interactive shell:-i
crée un connexion shell poursomeUser
, ce qui implique les éléments suivants:someUser
's spécifiques à l'utilisateur shell de profil, si elle est définie, est chargé.$HOME
points desomeUser
's home, donc il n'y a pas besoin de-H
(bien que vous pouvez toujours spécifier)someUser
's home directory.-s
crée un non-shell de login:~/.bashrc
)-H
, l'usurpation de l'identité d'processus de rapport de la original répertoire home de l'utilisateur dans$HOME
.À l'aide d'un shell signifie que la chaîne d'arguments passés sur la ligne de commande PEUT être sous réserve de shell expansions - voir la plate-forme de différences spécifiques ci-dessous par l'usurpation de l'identité d'shell (éventuellement après le début de son expansion par l'invocation du shell), à comparer les deux commandes suivantes (qui utilisent unique guillemets pour empêcher l'expansion par le invoquant shell):
Ce shell est appelé est déterminé par "la COQUILLE variable d'environnement si elle est ou la coquille, comme spécifié dans passwd(5)" (selon
man sudo
). Notez qu'avec-s
c'est le invoquant environnement utilisateur qui compte, alors qu'avec-i
c'est le représenté de l'utilisateur.Noter qu'il y a plate-forme de différences en ce qui concerne shell liée à un comportement (avec
-i
ou-s
):sudo
sur Linux apparemment accepte uniquement un exécutable ou builtin nom que le première argument suivant-s
/-i
, alors que OSX permet de passer toute une ligne de commande shell; par exemple, OSX acceptesudo -u root -s 'echo $SHELL - $USER - $HOME - $PWD'
directement (pas besoin deeval
), alors que Linux n'est pas (que desudo 1.8.95p
).Les anciennes versions de
sudo
sur Linux ne s'appliquent PAS shell extensions arguments passés à une coquille; par exemple, avecsudo 1.8.3p1
(par exemple, Ubuntu 12.04),sudo -u root -H -s echo '$HOME'
simplement fait l'écho de la chaîne littérale "$HOME" au lieu de l'expansion de la variable de référence dans le contexte de l'utilisateur root. À tout le moins ausudo 1.8.9p5
(par exemple, Ubuntu 14.04) ce problème a été corrigé. Par conséquent, pour assurer l'expansion sur Linux, même avec les ancienssudo
versions, passer les de la commande entière comme un seul argument àeval
; par exemple:sudo -u root -H -s eval 'echo $HOME'
. (Bien que pas nécessaire sur OSX, cela fonctionne aussi.)La
root
de l'utilisateur$SHELL
variable contient/bin/sh
sur OSX 10.9, alors qu'il est/bin/bash
sur Ubuntu 12.04.Si le processus consiste à usurper l'identité d'un shell ou non, de son environnement sont les suivantes variables, reflétant l'invocation de l'utilisateur et de commande:
SUDO_COMMAND
,SUDO_USER
,SUDO_UID=
,SUDO_GID
.Voir
man sudo
etman sudoers
pour beaucoup plus de subtilités.Coup de chapeau à @DavidW et @Andrew pour l'inspiration.
De BASH, vous pouvez trouver un utilisateur
$HOME
répertoire en le faisant précéder de l'utilisateur, l'ID de connexion avec un tilde. Par exemple:Cela se fera l'écho d'utilisateur
bob
's$HOME
répertoire.Cependant, vous dites que vous voulez être en mesure d'exécuter un script à un utilisateur particulier. Pour ce faire, vous devez configurer sudo. Cette commande permet d'exécuter différentes commandes qu'un utilisateur particulier. Par exemple, pour exécuter
foo
en tant qu'utilisateurbob
:Cela va démarrer un nouveau shell, et le
-i
permettra de simuler une connexion avec l'utilisateur par défaut de l'environnement et de la coquille (ce qui signifie que lefoo
commande sera exécutée à partir de labob's
$HOME` annuaire.)Sudo est un peu complexe à configurer, et vous avez besoin d'être un super-utilisateur juste pour être en mesure de voir les frémit fichier (généralement
/etc/sudoers
). Toutefois, ce fichier a généralement plusieurs exemples que vous pouvez utiliser.Dans ce fichier, vous pouvez spécifier les commandes vous permet de spécifier qui peut exécuter une commande, comme utilisateur, et si oui ou non l'utilisateur doit entrer son mot de passe avant l'exécution de cette commande. Normalement, c'est la valeur par défaut (parce qu'il montre que c'est l'utilisateur et non pas quelqu'un qui est venu alors que l'utilisateur a l'obtention d'un Coca.) Toutefois, lorsque vous exécutez un script shell, généralement, vous souhaitez désactiver cette fonctionnalité.
-i
et-s
semblent être mutuellement exclusifs. Juste-i
devrait être suffisant.~$different_user
à une variable et de la transformer en$HOME
. Pouvez-vous me donner un exemple?user_home=~$different_user
. Remarque il n'y a pas de guillemets autour de la~$different_user
. Votre système d'exploitation peut également vous empêcher de réaffectationHOME
car elle n'a pas de signification particulière. Êtes-vous à l'aide desudo
? C'est la méthode recommandée.Pour l'amour d'une réponse alternative pour ceux qui cherchent un léger moyen de le trouver d'accueil d'un utilisateur dir...
Plutôt que de vous embêter avec
su
hacks, ou de la peine avec la surcharge de lancer un autrebash
shell juste de trouver la$HOME
variable d'environnement...Léger Simple Homedir Requête via Bash
Il existe une commande spécialement pour cela:
getent
getent passwd someuser | cut -f6 -d:
getent
peut faire beaucoup plus... il suffit de voir les page de man. Lepasswd
nsswitch de la base de données sera de retour l'entrée utilisateur dans/etc/passwd
format. Divisée sur le côlon:
d'analyser les champs.Il doit être installé sur la plupart des systèmes Linux (ou tout système qui utilise GNU Lib C (RHEL:
glibc-common
, Deb:libc-bin
)getent
est spécifique à Linux, comme vous le dites; un moyen plus simple et la plate-forme neutre façon est d'utiliser bash est tilde expansion avec le nom de l'utilisateur d'intérêt (eval
est nécessaire, parce que le nom d'utilisateur doit être donné comme un non cotées littérale pour l'expansion de travailler):eval echo "~$different_user"
- les mises en garde habituelles pour l'utilisation deeval
appliquer.eval echo "~$(who -m | awk '{ print $1 }')"
ou tout simplementeval echo "~"
. Sur Mac OS X, il y a ladscl
utilitaire, mais il est de sortie est beaucoup plus difficile à analyser, et vous oblige à déjà passer dans le/Users
homedir ou liquide (par exemple:dscl . -read /Users/$(who -m | awk '{ print $1 }')
oudscl . -search /Users UniqueID $(id -u)
). Il est probablement plus facile sur certaines plates-formes de seulement utiliser bash, ou de faire une sorte de base de la détection de système d'exploitation de toute façon.eval
à tous: non cotées~
sera de retour l'actuel répertoire home de l'utilisateur (par exemple,echo ~
). Si vous avez vraiment besoin de l'utilisateur actuel de l'utilisateur explicitement,$USER
est la plus simple, efficace et conforme à POSIX;whoami
est aussi simple, mais relativement coûteux et non-POSIX. Votrewho -m
commande, bien que conforme à POSIX, est encore plus cher. Pour conclure: oui, à l'aide d'un compatible POSIX shell (par exemple, Bash) est la plus simple, la plus efficace et portable.getent
est spécifique à Linux, mais pourquoi? Il semble à l'évidence utile d'avoir ce truc (en gros une interface de ligne de commande pour interroger une base de données, même si la mise en œuvre via des fichiers texte) et doit être facilement portable, aussi. Eh bien, il doit en outre disposer d'un moyen pour extraire des valeurs de l'enregistrement. Cela permettrait d'éviter le rond-point de l'utilisation decut
getent
au lieu de simplement lire à partir de/etc/passwd
est à cause du potentiel pour les différentes sources d'utilisateur & l'authentification de la connexion de données back-end. Il existe une variété de mécanismes pour l'utilisateur de base de données tels quesssd
(sss/LDAP), NIS et NIS+. Pour plus d'informations, veuillez consulter cette SE sur la Réponse nsswitch.conf. La nécessité pour la coupe supplémentaire n'est pas la plus grande, je serais d'accord, mais c'est ce que l'outil de sorties. La vraie raison pour l'utilisation degetent
est d'essayer de requête de l'utilisateur configuré principale base de données sur le système.Vous voulez le
-u
option poursudo
dans ce cas. À partir de laman
page:Si vous n'avez pas besoin de l'exécuter en tant que, vous pourriez passer à leur répertoire home avec
~<user>
. Comme dans, de se déplacer dans mon répertoire home vous utilisezcd ~chooban
.-u
option avec la commande?sudo -u $different_user su -
?su
en tant qu'autre utilisateur. Utilisez la commande que vous souhaitez exécuter en tant qu'utilisateur. Par exemple,sudo -u $different_user $command
sudo
dans un seul script, si c'est ce que vous avez besoin. L'utilisation de sudo et de la configuration est la meilleure façon d'aller à ce sujet. Vos commandes peuvent exécuter en tant qu'utilisateur sans demander de confirmation. Autrement, vous devez vous connecter en tant qu'utilisateur, et qui lance un nouveau shell qui signifie que vous devez exécuter manuellement vos commandes. Vous voulez le faire automatiquement.Si vous voulez:
Inspiré par cette réponse, voici la version adaptée de votre script:
Lorsque vous l'exécutez, vous devriez obtenir ceci:
#!/usr/bin/env bash
comme shebang.Cela fonctionne sous Linux. Vous ne savez pas comment il se comporte dans d'autres *nixes.
J'étais également à la recherche de ce, mais ne veulent pas emprunter l'identité d'un utilisateur de simplement acquérir un chemin!
user_path=$(grep $username /etc/passwd|cut -f6 -d":");
Maintenant, dans votre script, vous pouvez vous référer à
$user_path
dans la plupart des cas, il serait/home/username
Suppose: Vous avez déjà réglé
$username
avec la valeur de la destination d'utilisateurs nom de l'utilisateur.Source: http://www.unix.com/shell-programming-and-scripting/171782-cut-fields-etc-passwd-file-into-variables.html
Rapide et sale, et de le stocker dans une variable:
J'ai eu du mal avec cette question, parce que je cherchais un moyen de le faire dans un script bash pour OS X, donc /etc/passwd, il était hors de question, et mon script est destiné à être exécuté en tant que root, donc les solutions de l'invocation eval ou bash -c dangereux car ils ont permis l'injection de code dans la variable spécifiant le nom de l'utilisateur.
Voici ce que j'ai trouvé. Il est simple et ne pas mettre une variable à l'intérieur d'un shell interne est exécuté. Cependant, il n'est besoin que le script sera exécuté par root comme il sudos dans le compte d'utilisateur spécifié.
En supposant que $SOMEUSER contient un nom d'utilisateur valide:
J'espère que cela aide quelqu'un!
Si l'utilisateur n'existe pas,
getent
retournera une erreur.Voici une petite coquille fonction qui n'ignorent pas le code de sortie de
getent
:Voici un exemple d'utilisation:
Le titre de cette question est Comment obtenir le répertoire $HOME de l'utilisateur différent dans le script bash? et c'est ce que les gens viennent ici de Google pour les trouver.
Si vous faites cela parce que vous utilisez quelque chose comme
root
ensuite, vous pouvez utiliser la puissance de sudo:Si non, vous pouvez l'obtenir à partir d'
/etc/passwd
. Il y a déjà beaucoup d'exemples de l'aideeval
etgetent
, donc je vais donner une autre option:Je voudrais vraiment que l'utilisation que l'on si j'avais un script bash avec beaucoup d'autres awk oneliners et aucune utilisation de
cut
. Alors que beaucoup de gens aiment à "code de golf" pour utiliser le moins de caractères pour accomplir une tâche, je préfère l'outil de "golf", parce que l'utilisation de moins d'outils donne à votre script d'un petit "compatibilité de l'empreinte". Aussi, c'est moins l'homme pages de votre collègue ou de l'avenir de l'auto à lire pour en comprendre le sens.La sortie de
getent passwd username
peut être analysé avec un Bash expression régulière