Comment définir des variables d'environnement globales au démarrage via un script et les rendre disponibles pour une application qui s'exécute avant la connexion?

17

J'ai un service qui s'exécute au démarrage, et dans ce service, il appelle un script bash en arrière-plan qui exporte certaines variables d'environnement. Le problème que j'ai est que ces variables d'environnement ne sont pas envoyées au parent du processus d'arrière-plan, donc dès que mon script est terminé, elles disparaissent.

De plus, après l'exécution du script, le service appelle un autre script qui démarre une application que j'ai. Cette application doit avoir accès à ces variables d'environnement.

Le système RHEL sur lequel je l'exécute est censé ne jamais être connecté à l'utilisateur, il démarre uniquement et démarre l'application. Je sais cependant que les variables d'environnement d'un processus / shell parent ne peuvent pas vraiment être définies par un shell de processus d'arrière-plan enfant.

J'ai besoin d'un moyen de le faire à travers un script qui est appelé par mon service (pas nécessairement en arrière-plan cependant), pas en les ajoutant à mon service (qui n'a pas fonctionné non plus pour moi) et pas en les stockant dans un /etc/environmentou .profileou quelque chose comme ça.

Dans mon service, j'ai essayé d'ajouter les variables d'environnement (pas ce que je veux faire cependant):

    export TEST=192.168.1.1

J'ai également essayé ceci à mon service:

    TEST=192.168.1.1
    export TEST=${TEST}

J'ai essayé de changer la façon dont mon service appelle le script bash:

    /bin/asdf/script &

J'ai également essayé de sourcer le script pour qu'il s'exécute dans le même shell (que j'ai obtenu de cela ):

    . ./bin/asdf/script
    #I'm very confused why this didn't work

J'ai aussi trouvé cela qui avait l'air intéressant mais ça ne marchait pas vraiment dans mon cas.

sqenixs
la source

Réponses:

12

Vous pouvez essayer de mettre un script pour rassembler les variables dans /etc/profile.d/

Exemple:

/etc/profile.d/somescript.sh

#!/bin/bash
TEST=$(cat /var/somefile)
export $TEST

/etc/profileeffectue un appel qui exécutera n'importe quel script /etc/profile.d/, et cela s'applique à tous les utilisateurs du système, y compris root.

madflojo
la source
Tu tiens peut-être quelque chose ici. Je ne veux pas faire exactement cela, car le script ne peut pas être situé dans le répertoire / etc pour des raisons IA. Mais je pense que je peux créer un lien symbolique là-bas qui pointe vers mon script. Mais pour compliquer les choses, certaines des variables d'environnement définies par le script proviennent de variables d'environnement définies par le service. Donc, cela pourrait ne pas fonctionner, car les variables doivent déjà être définies avant la fin du script de service, mais pas trop tôt ou les variables d'environnement nécessaires n'auront pas encore été créées par le service.
sqenixs
Je suppose que je peux me débarrasser de la dépendance des variables définies dans le service. Dans ce cas, je pense que cela fonctionnera, tant que le script sera exécuté avant le démarrage du service. Savez-vous quand le shell de connexion est démarré? Ou puis-je contrôler le démarrage du shell de connexion? Je n'ai pas de service pour cela dans le répertoire rcX.d pour mon niveau d'exécution.
sqenixs
1

Il n'y a aucun moyen pour un processus d'influencer l'environnement d'un autre processus existant. Les processus n'influencent que l'environnement de leurs processus enfants.

Vous devez donc définir ces variables d'environnement dans un ancêtre de l'application qui en a besoin. Au lieu d'avoir votre service invoquer séparément le script bash de définition d'environnement et l'application, demandez à votre service d'appeler un script bash qui définit les variables d'environnement puis lance l'application.

#!/bin/bash
. /path/to/environment/variable/setter.bash
exec /path/to/application
Gilles 'SO- arrête d'être méchant'
la source
D'après ce que j'ai lu en ligne, il y a des hacks (quelque chose ayant à voir avec eval sur un script source, ou en utilisant gdb) pour le faire fonctionner. Je ne suis pas trop intéressé par le fait qu'il soit en arrière-plan, si je peux exécuter les commandes dans le "shell" actuel (êtes-vous dans un shell au démarrage lorsque votre service s'exécute?), Ce serait bien aussi.
sqenixs
Malheureusement, je ne peux pas démarrer l'application à partir du service, car il existe de nombreux processus différents qui sont démarrés et des éléments configurés à partir du script de démarrage de l'application, et ils doivent être séparés du service pour IA.
sqenixs
@sqenixs Un shell est un processus comme les autres. Il n'y a rien de tel que «être dans une coquille». Lorsque vous parlez de «eval sur un script source», c'est un protocole où un programme (qui peut ne pas être un script shell) imprime des définitions dans la syntaxe shell, et un script shell les interprète. La définition de variables d'environnement avec gdb pourrait fonctionner, ou cela pourrait n'avoir aucun effet, ou cela pourrait planter votre application; comme vous pouvez l'imaginer, l'utilisation d'un débogueur en production n'est pas recommandée (et, encore une fois, pour une bonne raison).
Gilles 'SO- arrête d'être méchant'
Il existe probablement une solution à votre problème, mais vous devez être plus précis avec vos besoins. Dans votre question, vous écrivez «après l'exécution du script, le service appelle ensuite un autre script qui démarre une application». Vous semblez donc avoir une solution: définir les variables d'environnement à l'intérieur de cet autre script. Mais dans un commentaire, vous écrivez que vous «ne pouvez pas démarrer l'application à partir du service». Alors, c'est quoi?
Gilles 'SO- arrête d'être méchant'
peut-être, créer ou configurer l'environnement de / sbin / init au démarrage. Comme chaque processus est de toute façon un enfant d'init, le processus enfant peut acquérir l'environnement. Juste une pensée / supposition.
Nikhil Mulley