Le problème
Dans un script bash, j'utilise la commande ...
Sudo -u node bash
.. pour passer de la racine à un utilisateur autre que Sudo, et cela échoue.
Le contexte
J'écris un script provision.sh
pour Vagrant afin de configurer un serveur exécutant Ubuntu 16.04.3 avec tous les packages nécessaires à la fourniture d'une application avec Meteor 1.6.
Une étape requise consiste à installer nvm
en tant qu'utilisateur non root. Une fois que nvm
est installé, vous devez vous déconnecter et vous reconnecter pour pouvoir activer nvm
name__. Je crée donc un utilisateur non-Sudo nommé meteor
et souhaite y basculer lorsque je télécharge et installe nvm
name__.
Par la suite, je souhaite redevenir root
et me connecter immédiatement sous le nom meteor
name__, afin de pouvoir utiliser nvm
pour installer Node.js.
Vous trouverez ci-dessous un script très commenté. Vagrant exécute ce script chaque fois que j'appelle vagrant reload --provision
.
Quelle commande devrais-je utiliser à la place de Sudo -u node bash
?
echo "# whoami" && whoami && echo "^^^^ root expected"
echo "As root, create non-Sudo user meteor:"
pass=$(Perl -e 'print crypt($ARGV[0], "password")' $password)
useradd -m -p $pass meteor
echo "User meteor created. ls -al /home/meteor:"
ls -al /home/meteor
echo "Install curl as root:"
apt-get install -y curl
echo "Trying Sudo -u meteor bash"
Sudo -u meteor bash #### THIS IS THE LINE THAT FAILS ###
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
echo "ls -al /home/meteor/.nvm # should be populated"
ls -al /home/meteor/.nvm
echo "ls -al /root/.nvm # should not exist"
ls -al /root/.nvm
echo "command -v nvm will fail silently until we log out and back in again"
#command -v nvm
exit
#### Because the script is still running as root, it halts here ####
echo "# whoami" && whoami && echo "^^^^ should be root"
Sudo -u meteor bash
echo "$ whoami" && whoami && echo "^^^^^^ should be meteor"
echo "command -v nvm should work now"
command -v nvm
Si vous démarrez votre script avec des autorisations root mais que vous devez exécuter certaines commandes en tant qu'utilisateur non root spécifique, vous pouvez utiliser Sudo
avec l'option -u
pour exécuter une seule commande avec par exemple.
Sudo -u USERNAME whoami # outputs USERNAME's user name
ou démarrez un sous-shell et exécutez vos commandes, par exemple:
Sudo -u USERNAME bash -c 'whoami;echo $USER' # outputs USERNAME's user name twice
La ligne de votre script n'échoue pas réellement, vous ne faites que bash
en tant qu'utilisateur meteor
et comme bash
n'a rien à faire, il se ferme et le shell racine d'origine exécute le reste du script. Ce que vous voulez réellement faire (je suppose) est:
…
echo "Trying Sudo -u meteor bash"
Sudo -u meteor bash -c '\
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |\
bash
'
echo "ls -al /home/meteor/.nvm # should be populated"
…
Un autre moyen de réaliser la même chose est un ici document :
…
echo "Trying Sudo -u meteor bash"
Sudo -u meteor bash <<EOF
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |\
bash
EOF
echo "ls -al /home/meteor/.nvm # should be populated"
…
#! /bin/bash
# (GPL3+) Alberto Salvia Novella (es20490446e)
execute () {
function="${1}"
command="${2}"
error=$(eval "${command}" 2>&1 >"/dev/null")
if [ ${?} -ne 0 ]; then
echo "${function}: $error"
exit 1
fi
}
executeAsNonAdmin () {
function="${1}"
command="${2}"
eval setPasswordAsker="Sudo_ASKPASS=/usr/libexec/openssh/ssh-askpass"
run="runuser ${Sudo_USER} --session-command=\"${setPasswordAsker}\" --command=\"${command}\""
execute "${function}" "${run}"
}
executeAsNonAdmin "" "${@}"