web-dev-qa-db-fra.com

Quels fichiers proviennent de l'utilisation de su -c?

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!

7
Kulgar

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.

9
heemayl