Script BASH pour définir les variables d'environnement ne fonctionnant pas

137

J'ai écrit le script suivant pour définir certaines variables d'environnement lorsque cela est nécessaire.

#!/bin/sh
export BASE=/home/develop/trees
echo $BASE
export PATH=$PATH:$BASE
echo $PATH

Ci-dessous la commande et les résultats que je peux voir sur mon terminal: le script s'exécute, mais les variables ne sont pas définies à la fin.

~$: ./script.sh
/home/develop/trees
/bin:......:/home/develop/trees
~$: echo $BASE

~$: 

Qu'est-ce qui ne va pas? Merci d'avance. Mirko

MirkoZa
la source

Réponses:

194

exportexporte l'affectation de variable vers les processus enfants du shell dans lequel la exportcommande a été exécutée. Votre environnement de ligne de commande est le parent du shell du script. Il ne voit donc pas l'affectation de variable.

Vous pouvez utiliser la commande .(ou source) bash pour exécuter les commandes de script dans l'environnement shell actuel et obtenir ce que vous voulez, par exemple:

source ./script.sh
echo "$BASE"

Produira

/home/develop/trees

La sourcecommande, souvent vue dans les scripts, est un synonyme bash pour ., qui fait partie du standard POSIX ( .est donc disponible au tiret, par exemple, mais sourcene l’est pas).

. ./script.sh     # identical to "source ./script.sh"

( . script.shet source script.shcherchera d’abord script.shdans PATH, il est donc plus sûr de spécifier le chemin vers script.sh.)

muru
la source
29
Il n'est pas nécessaire exportde transmettre des variables aux sous-shell, un sous-shell est une copie de votre shell actuel, y compris les variables et les fonctions, etc. Les variables exportées sont copiées dans les nouveaux processus générés à partir du shell, que ce processus soit un autre shell ou non. Deuxièmement, .la commande POSIX pour le sourcing. Bash ajoute sourceun synonyme plus lisible, mais vous ne pouvez pas compter sur sa disponibilité dans sh. Enfin . ./scriptau lieu de . scriptsi vous voulez éviter les surprises. mywiki.wooledge.org/BashFAQ/0/060
geirha
Notez que si vous sourcez un script ET utilisez un canal, l'environnement généré n'est pas disponible pour le parent. Par exemple, 'source setit.sh' va bien. 'source setit.sh | tee setit.log' ne va pas. Surprenant. Pas intuitif.
Gaoithe
10

Lorsque vous exécutez un script, il s'exécute dans un sous-shell. Les variables ne sont valables que dans le contexte de ce sous-shell. Placez-les dans votre .bashrcou .profileet lisez sur les variables et les sous-shell . L' exportinstruction fonctionne en bas de la hiérarchie (shell actuel et tous ses sous-shell) pas comme dans votre exemple.

Alternativement (si vous voulez vraiment que le script affecte l'environnement de votre shell actuel), exécutez-le en tant que:

. ./script.sh

Cela provoque son exécution dans votre shell actuel mais ne transmet pas non plus de variables dans la hiérarchie.

embrouiller
la source
5

Je veux souvent définir une variable d'environnement sans tracas.

Voici ce que j'ajoute à mon .bashrc pour implémenter cette commodité.

defect() {
    if [ $1 ] && [ -z $2 ]
    then
        eval 'export DEFECT=$1'
        return 0
    else
        echo 'Usage: defect {number}'
        return 1
    fi
}
Jlettvin
la source
-1

Vous pouvez essayer quelque chose comme ça

CURRENT_DIR=`pwd`
echo "SOME_PATH is pointing to ${CURRENT_DIR}"
#Export SOME_PATH for current working directory
export SOME_PATH=${CURRENT_DIR}
Silentsudo
la source