Disons que j'ai un script shell / bash nommé test.sh
avec:
#!/bin/bash
TESTVARIABLE=hellohelloheloo
./test2.sh
Mon test2.sh
ressemble à ceci:
#!/bin/bash
echo ${TESTVARIABLE}
Cela ne fonctionne pas. Je ne veux pas passer toutes les variables comme paramètres car à mon humble avis, c'est exagéré.
Y a-t-il une manière différente?
Réponses:
Vous avez essentiellement deux options:
export TESTVARIABLE
) avant d'exécuter le 2ème script.. test2.sh
- dire et il fonctionnera dans le même shell. Cela vous permettrait de partager facilement des variables plus complexes telles que des tableaux, mais cela signifie également que l'autre script pourrait modifier des variables dans le shell source.METTRE À JOUR:
Pour utiliser
export
pour définir une variable d'environnement, vous pouvez soit utiliser une variable existante:Cela devrait fonctionner à la fois dans
bash
etsh
.bash
permet également de le combiner comme ceci:Cela fonctionne également dans my
sh
(ce qui se trouve êtrebash
, vous pouvez utiliserecho $SHELL
pour vérifier). Mais je ne pense pas que cela fonctionne dans toussh
, alors mieux vaut jouer la sécurité et les séparer.Toute variable que vous exportez de cette manière sera visible dans les scripts que vous exécutez, par exemple:
cendre:
b.sh:
Ensuite:
Le fait que ce soient tous les deux des scripts shell est également accessoire. Les variables d'environnement peuvent être passées à n'importe quel processus que vous exécutez, par exemple si nous avons utilisé python à la place, cela pourrait ressembler à:
cendre:
b.py:
Approvisionnement:
Au lieu de cela, nous pourrions nous approvisionner comme ceci:
cendre:
b.sh:
Ensuite:
Cela "importe" plus ou moins
b.sh
directement le contenu de et l'exécute dans le même shell . Notez que nous n'avons pas eu à exporter la variable pour y accéder. Cela partage implicitement toutes les variables que vous avez, ainsi que permet à l'autre script d'ajouter / supprimer / modifier des variables dans le shell. Bien sûr, dans ce modèle, vos deux scripts doivent être dans la même langue (sh
oubash
). Pour donner un exemple de la façon dont nous pourrions passer des messages dans les deux sens:cendre:
b.sh:
Ensuite:
Cela fonctionne aussi bien dans
bash
. Cela facilite également le partage de données plus complexes que vous ne pourriez pas exprimer en tant que variable d'environnement (du moins sans une lourde charge de votre part), comme des tableaux ou des tableaux associatifs.la source
Fatal Error a donné une possibilité simple: source votre deuxième script! si vous craignez que ce second script puisse altérer certaines de vos précieuses variables, vous pouvez toujours le rechercher dans un sous-shell:
Les parenthèses feront apparaître la source dans un sous-shell, de sorte que le shell parent ne verra pas les modifications
test2.sh
possibles.Il y a une autre possibilité qui devrait certainement être référencée ici: use
set -a
.De la référence POSIX
set
:À partir du manuel Bash :
Donc dans votre cas:
Notez que les spécifications spécifient uniquement que
set -a
la variable est marquée pour l'exportation. C'est:fera écho
c
et non une ligne vide nib
(c'est-à-direset +a
qu'il ne désélectionne pas pour l'exportation, ni ne «sauvegarde» la valeur de l'affectation uniquement pour l'environnement exporté). C'est, bien entendu, le comportement le plus naturel.Conclusion: utiliser
set -a
/set +a
peut être moins fastidieux que d'exporter manuellement toutes les variables. Il est supérieur à l'approvisionnement du deuxième script, car il fonctionnera pour n'importe quelle commande, pas seulement celles écrites dans le même langage shell.la source
Il existe en fait un moyen plus simple que d'exporter et de désarmer ou de réapprovisionner (au moins dans bash, tant que vous êtes d'accord pour passer les variables d'environnement manuellement):
laissez a.sh être
et b.sh être
La sortie observée est
La magie réside dans la dernière ligne
a.sh
, oùMessage
, pour seulement la durée de l'invocation de./b.sh
, est réglé sur la valeursecret
dea.sh
. En gros, c'est un peu comme des paramètres / arguments nommés. De plus, cela fonctionne même pour des variables telles que$DISPLAY
, qui contrôle le serveur X dans lequel une application démarre.N'oubliez pas que la longueur de la liste des variables d'environnement n'est pas infinie. Sur mon système avec un noyau relativement vanille,
xargs --show-limits
me dit que la taille maximale du tampon d'arguments est de 2094486 octets. Théoriquement, vous utilisez mal les scripts shell si vos données sont plus grandes que cela (tuyaux, n'importe qui?)la source
Ajoutant à la réponse d'erreur fatale, il existe une autre façon de passer les variables à un autre script shell.
La solution suggérée ci-dessus présente certains inconvénients:
using Export
: Cela entraînera la présence de la variable hors de sa portée, ce qui n'est pas une bonne pratique de conception.using Source
: Cela peut provoquer des conflits de noms ou un écrasement accidentel d'une variable prédéfinie dans un autre fichier de script shell qui a généré un autre fichier.Il existe une autre solution simple que nous pouvons utiliser. Compte tenu de l'exemple que vous avez posté,
test.sh
test2.sh
production
Il est également important de noter que
""
sont nécessaires si nous passons des chaînes de mots multiples. Prenons un autre exemplemaster.sh
slave1.sh
slave2.sh
production
Cela se produit pour les raisons bien décrites dans ce lien
la source
source
est en fait une bonne chose. Concernant votre souci: écrasement accidentel d'une variable prédéfinie , vous pouvez toujours vous procurer dans un sous-shell. Cela résout complètement le problème.( . ./test2.sh )
. Les parenthèses obligeront Bash à exécuter son contenu dans un sous-shell.Dans Bash, si vous exportez la variable dans un sous-shell, en utilisant les parenthèses comme indiqué, vous évitez de divulguer les variables exportées:
L'avantage ici est qu'après avoir exécuté le script à partir de la ligne de commande, vous ne verrez pas un $ TESTVARIABLE filtré dans votre environnement:
la source
$
invite de ligne de commande ) ne verra jamais le fichier exporté$TESTVARIABLE
. L'exportation transmet simplement une copie d'une variable à tous les processus enfants suivants . Il n'est pas possible de transmettre des variables de sauvegarde de la chaîne aux processus parents, sauf en enregistrant la valeur dans le stockage et en lisant ce stockage ultérieurement dans le script de processus parent. Le transfert vers une deuxième copie du script parent est possible, mais ce ne serait pas le même processus . Une excellente explication peut être trouvée ici .Une autre option utilise
eval
. Cela ne convient que si les chaînes sont approuvées. Le premier script peut faire écho aux affectations de variables:echo "VAR=myvalue"
Ensuite:
eval $(./first.sh) ./second.sh
Cette approche est particulièrement intéressante lorsque le second script pour lequel vous souhaitez définir des variables d'environnement n'est pas dans bash et que vous ne voulez pas non plus
export
les variables, peut-être parce qu'elles sont sensibles et que vous ne voulez pas qu'elles persistent.la source
Une autre façon, qui est un peu plus simple pour moi, consiste à utiliser des tubes nommés. Les canaux nommés fournissaient un moyen de synchroniser et d'envoyer des messages entre différents processus.
Rendre confus:
B.bash:
Usage:
B.bash attendra le message et dès que A.bash enverra le message, B.bash continuera son travail.
la source