Comment rendre le service unix voir les variables d'environnement?

52

J'ai défini ma variable d'environnement en utilisant /etc/profile:

export VAR=/home/userhome

Alors si je le fais echo $VARmontre/home/userhome

Mais lorsque je mets référence à cette variable dans le /etc/init.d/servicenamefichier, il ne peut pas trouver cette variable. Quand j'exécute en service servicename statusutilisant un /etc/init.d/servicenamefichier avec le contenu suivant:

case "$1" in
status)    
    cd $VAR/dir
    ;;
esac

ça dit /dir: No such file or directory

Mais ça marche si je cours /etc/init.d/servicename statusau lieu deservice servicename status

Comment puis-je faire en sorte qu'un service unix voie les variables d'environnement?

altern
la source
Notez que l' invocation du système 5 rcdirectement le script aussi ne fonctionne pas de cette façon sur les systèmes d'exploitation systemd, comme toutes les invocations du script sont transformées en invocations systemctlpar un crochet caché.
JdeBP

Réponses:

70

Le problème est servicebandes toutes les variables de l' environnement mais TERM, PATHet ce LANGqui est une bonne chose. Si vous exécutez le script directement, rien ne supprime les variables d'environnement, donc tout fonctionne.

Vous ne voulez pas vous fier à des variables d'environnement externes car au démarrage, la variable d'environnement n'est probablement pas présente et votre système init ne le configurera probablement pas de toute façon.

Si vous souhaitez toujours utiliser de telles variables, sourcez un fichier et lisez-les, par exemple créez-les /etc/default/servicenameavec le contenu:

VAR=value

et le source de votre script init, par exemple:

[ -f /etc/default/service-name ] && . /etc/default/service-name

if [ -z "$VAR" ] ;  then
  echo "VAR is not set, please set it in /etc/default/service-name" >&2
  exit 1
fi

case "$1" in
status)    
    cd "$VAR"/dir
    ;;
esac
Ulrich Dangel
la source
13
Très utile, merci. Pour les autres débutants sur Linux, voici le truc cryptique de Bash. [ ... ]est un raccourci pour un test conditionnel; voir cette réponse . -fest un ifargument pour vérifier si le fichier existe. &&est un opérateur de court-circuit: effectuez la deuxième commande uniquement si la première quitte avec 0. .opérateur source ou point: lisez et exécutez les commandes à partir de l'argument filename. -zest un ifargument pour vérifier une chaîne de longueur nulle. >&2envoyer la sortie à stderr. Voir aussi Introduction à if .
Mark Berry
@MarkBerry -ffait partie [, non if.
Chris Down
@ ChrisDown, merci. Donc " [ ... ]est un raccourci pour une testcommande conditionnelle ; voir cette réponse . -fEst un testargument pour vérifier si un fichier existe."
Mark Berry
@ MarkBerry Correct. Vous pouvez considérer [(ou test) simplement comme une autre commande. Tout ce ifque vous avez à faire est de prendre des mesures en fonction du statut de sortie.
Chris Down
J'ai rencontré une situation similaire à celle-ci, mais je n'ai pas besoin $VARd'être dans le script init, j'ai besoin qu'elle soit disponible pour un programme différent 2 ou 3 appels en aval du script init. Par exemple. Le script init appelle start-stop-daemon qui appelle le programme 1 (Java) qui appelle le programme 2 dont il a besoin $VAR. J'ai essayé le truc dans cette réponse mais cela ne semble pas fonctionner dans ma situation. Comment puis-je m'assurer qu'il $VARsera disponible pour le programme 2?
FrustratedWithFormsDesigner
1

Dans mon cas, il me fallait un RAILS_ENVqui a été mis en /etc/bash.bashrc: export RAILS_ENV=staging. J'ai ajouté $(grep RAILS_ENV /etc/bash.bashrc)et cela a rendu la variable disponible pour le script. Je l'ai fait de cette façon, donc je n'ai pas eu à inclure le reste du fichier.

geermc4
la source
-1

Une solution laide qui fonctionnera également:

function exec() {
    args=( $@ )
    command=${args[0]}
    dummy=${args[1]}
    whoami=`whoami`
    if [ -z "$dummy" ]; then
        me=`basename $0`
        runuser -l ${whoami} -c "bash /etc/init.d/${me} ${command} dummy"
    else
       printenv
   fi
}

case $1 in
    status)
        status
        ;;
    start|stop|kill|restart)
        exec $*
        ;;
    *)
        usage
esac
Maksim
la source