Contexte
Vous travaillez sur Ubuntu LTS 14.04. Vous êtes connecté en tant qu'utilisateur root. Vous exécutez la commande suivante:
exec su simple_user -c "/bin/bash /etc/init.d/simple_user_service"
Ainsi, le "simple_user_service" est lancé avec les privilèges "simple_user" et non les privilèges root.
Question
Il semble que "exec su simple_user -c" ne source ni .bashrc, ni .profile, ni aucun autre fichier de source normale pour le nouveau terminal Shell interactif. J'ai confirmé cela en ajoutant cette ligne au fichier simple_user .bashrc:
export TEST="Hello"
Ensuite, dans mon script d'initiation "simple_user_service":
#!/bin/bash
### BEGIN INIT INFO
# Provides: test_script
# X-Interactive: true
# Short-Description: Test script
### END INIT INFO
echo $TEST
Lorsque j'exécute le script, rien n'est imprimé, mais si j'exécute les commandes suivantes:
su simple_user
echo $TEST
> Hello
La variable TEST est définie et imprimée correctement.
Je me demandais donc: "exec su simple_user -c" commande-t-il des fichiers de profil/utilisateurs bas_s simple_user? Si oui, y a-t-il un moyen de savoir lesquels?
Merci beaucoup pour votre aide!
[Modifier - 2 heures plus tard]
Grâce à la réponse que j'ai reçue, j'ai compris plus précisément les instructions "homme bash". J'ai trouvé ça:
When bash is started non-interactively, to run a Shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and
uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed:
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
but the value of the PATH variable is not used to search for the file name.
C’est vraiment intéressant, car vous pouvez définir BASH_ENV sur un fichier qui exécute des commandes spécifiques chaque fois que vous utilisez "su simple_user -c" sans avoir à charger la logique interactive complète.
Donc, avant d’exécuter su simple_user -c
, vous pouvez simplement faire:
export BASH_ENV=~/.bash_script
Et définissez les éléments dans votre fichier simple_user .bash_script, par exemple:
export TEST="Hello"
Ensuite, lorsque j'exécute le script "simple_user_service", "Bonjour" est correctement imprimé.
C'était vraiment utile pour moi car j'avais besoin de cela pour charger tout l'environnement "rvm" (Ruby) pour exécuter un script spécifique.
Voulez-vous en savoir plus?
Pourquoi tout ce problème?
Parce que j’ai installé Ruby _ god: http://godrb.com/ pour surveiller ce script spécifique (un travail retardé).
Et j'utilise "rvm" pour gérer différents rubis.
Et le script supprime automatiquement les privilèges si nécessaire en exécutant exec su application_user -c "/bin/bash application_script"
Comme Dieu a besoin de fonctionner avec les privilèges root et que rvm n'est chargé que dans des fichiers .bashrc/.profile, j'avais besoin d'un moyen de charger correctement l'environnement rvm dans mon script. Je pourrais simplement ajouter la commande rvm load dans le script, mais mon script aurait alors été dépendant de l'environnement et cela n'était pas acceptable.
J'ai donc ajouté ceci dans mon script avant la suppression des privilèges:
if [ -e "config/BASH_ENV" ]; then
export BASH_ENV=$(cat config/BASH_ENV)
fi
Grâce à cela, je peux charger rvm dans le fichier que j'ai défini dans le fichier config/BASH_ENV. Par exemple, cela pourrait être:
# In config/BASH_ENV file of your Rails app:
export BASH_ENV="~/.bash_script"
# In /home/simple_user/.bash_script
[[ -s "/etc/profile.d/rvm.sh" ]] && . "/etc/profile.d/rvm.sh" # Load RVM function
Ensuite, mon script et mon dieu fonctionnent comme prévu.
Je n’ai pas expliqué toutes ces choses avant d’obtenir des réponses pour que les lecteurs puissent se concentrer sur la vraie question.
Mais comme j'ai eu une bonne réponse et trouvé une bonne solution grâce à cela, j'ai écrit ce montage pour qu'il puisse être utile à d'autres.
Merci encore!
Quand tu fais:
_su some_user -c 'some_command'
_
_some_command
_ sera exécuté comme suit:
_bash -c 'some_command'
_
En supposant que bash
représente le shell _some_user
_ défini dans _/etc/passwd
_.
Maintenant, lorsque vous faites _bash -c 'some_command'
_, vous créez en gros une session non interactive (et bien sûr non-login) de bash
. Comme aucun fichier n’est généré par le shell en mode non interactif, aucun fichier n’est attendu.
Notez que _~/.profile
_ provient d'une session interactive de bash
et _~/.bashrc
_ de connexion, provient d'une session interactive non connectée de bash
. Notez également que les sources Ubuntu _~/.bashrc
_ de _~/.profile
_.
Consultez la section INVOCATION
de _man bash
_ pour avoir une idée plus précise.