Définir les variables d'environnement à partir du fichier

j'écris un script dans bash qui analyse des fichiers avec 3 variables dans un certain dossier, c'est l'une d'entre elles:

MINIENTREGA_FECHALIMITE="2011-03-31"
MINIENTREGA_FICHEROS="informe.txt programa.c"
MINIENTREGA_DESTINO="./destino/entrega-prac1"

Ce fichier est stocké dans ./conf/prac1

mon script minientrega.sh puis parsème le fichier en utilisant ce code:

cat ./conf/ | while read line; do
    export $line
done

mais quand j'exécute minientrega.sh prac1 dans la ligne de commande il ne définit pas les variables d'environnement

j'ai aussi essayé d'utiliser source ./conf/ mais le même le problème s'applique toujours

peut-être qu'il y a une autre façon de faire cela, j'ai juste besoin d'utiliser les variables d'environnement du fichier que je passe comme argument de mon script.

263
demandé sur b4hand 2013-10-12 11:01:29

19 réponses

problème avec votre approche est le export dans la boucle while se produit dans un sous-shell, et ces variables ne seront pas disponibles dans le shell courant (shell parent de While loop).

ajouter export commande dans le fichier lui-même:

export MINIENTREGA_FECHALIMITE="2011-03-31"
export MINIENTREGA_FICHEROS="informe.txt programa.c"
export MINIENTREGA_DESTINO="./destino/entrega-prac1"

ensuite, vous avez besoin de source dans le fichier dans l'interpréteur de commandes actuel en utilisant:

. ./conf/prac1

ou

source ./conf/prac1
115
répondu anubhava 2015-09-11 19:43:06

Cela pourrait être utile:

export $(cat .env | xargs) && rails c

la raison pour laquelle j'utilise ceci est si je veux tester des trucs .env dans ma console de rails.

gabrielf a trouvé un bon moyen de garder les variables locales. Cela résout le problème potentiel lorsqu'on passe d'un projet à l'autre.

env $(cat .env | xargs) rails

j'ai testé ceci avec bash 3.2.51(1)-release


mise à jour:

pour ignorer les lignes qui commencent par # , utilisez ceci (merci au commentaire de Pete ):

export $(grep -v '^#' .env | xargs)

Et si vous voulez unset toutes les variables définies dans le fichier, utilisez ceci:

unset $(grep -v '^#' .env | sed -E 's/(.*)=.*//' | xargs)

mise à jour:

pour gérer également les valeurs avec des espaces, utilisez:

export $(grep -v '^#' .env | xargs -d '\n')

sur les systèmes GNU ou:

export $(grep -v '^#' .env | xargs -0)

sur les systèmes BSD.

480
répondu Silas Paul 2018-05-30 09:03:36

-o allexport permet d'exporter toutes les définitions variables suivantes. +o allexport désactive cette caractéristique.

set -o allexport
source conf-file
set +o allexport
210
répondu user4040650 2016-08-24 09:09:58
set -a
. ./env.txt
set +a

si env.txt est comme:

VAR1=1
VAR2=2
VAR3=3
...
43
répondu Dan Kowalczyk 2017-08-30 23:34:22

l'option allexport est mentionnée dans quelques autres réponses ici, pour lesquelles set -a est le raccourci. La recherche de .env est vraiment mieux que la boucle au-dessus des lignes et l'exportation parce qu'il permet des commentaires, des lignes vierges, et même des variables d'environnement générées par des commandes. Mon. bashrc comprend les éléments suivants:

# .env loading in the shell
dotenv () {
  set -a
  [ -f .env ] && . .env
  set +a
}

# Run dotenv on login
dotenv

# Run dotenv on every new directory
cd () {
  builtin cd $@
  dotenv
}
18
répondu gsf 2015-12-04 16:57:59
eval $(cat .env | sed 's/^/export /')
17
répondu selvan 2015-04-07 10:35:47

Voici une autre solution sed , qui ne fonctionne pas eval ou ne nécessite pas de rubis:

source <(sed -E -n 's/[^#]+/export &/ p' ~/.env)

cela ajoute l'exportation, en gardant des commentaires sur les lignes commençant par un commentaire.

.contenu de l'env

A=1
#B=2

exemple

$ sed -E -n 's/[^#]+/export &/ p' ~/.env
export A=1
#export B=2

j'ai trouvé cela particulièrement utile lors de la construction d'un tel fichier pour le chargement dans un fichier unité systemd, avec EnvironmentFile .

17
répondu tutuDajuju 2016-04-06 16:21:58

SAVE=$(set +o) && set -o allexport && . .env; eval "$SAVE"

cela sauvera/restaurera vos options originales, quelles qu'elles soient.

utiliser set -o allexport a l'avantage de sauter correctement les commentaires sans un regex.

set +o par lui-même produit toutes vos options courantes dans un format que bash peut ensuite exécuter. Aussi pratique: set -o à lui seul, affiche toutes vos options actuelles dans un format convivial.

12
répondu jwfearn 2015-09-09 20:57:56

j'ai noté la réponse de user4040650 parce que c'est à la fois simple, et il permet des commentaires dans le fichier (c.-à-d. les lignes commençant par #), ce qui est très souhaitable pour moi, comme des commentaires expliquant les variables peuvent être ajoutés. Il suffit de réécrire dans le contexte de la question originale.

si le script est appelé comme indiqué: minientrega.sh prac1 , alors minientrega.sh aurait pu:

set -a # export all variables created next
source 
set +a # stop exporting

# test that it works
echo "Ficheros: $MINIENTREGA_FICHEROS"

ce qui suit a été extrait de l'ensemble documentation :

ce bâtiment est si compliqué qu'il mérite sa propre section. définir vous permet de changer les valeurs des options shell et les paramètres positionnels, ou pour afficher les noms et les valeurs de la coquille variable.

set [--abefhkmnptuvxBCEHPT] [- o option-name] [argument ...] set [+abefhkmnptuvxBCEHPT] [+o option-name] [argument ...]

si aucune option ou argument n'est fourni, set affiche les noms et les valeurs de tous les shell variables et fonctions, triées selon la localisation actuelle, dans un format qui peut être réutilisé comme entrée pour le réglage ou la réinitialisation variables actuellement définies. Les variables en lecture seule ne peuvent pas être réinitialisées. Dans POSIX mode, seules les variables shell sont listées.

lorsque les options sont fournies, elles paramètrent ou désactivent les attributs shell. Les Options, si elles sont spécifiées, ont la signification suivante:

- a chaque la variable ou la fonction qui est créée ou modifiée est donnée l'attribut d'exportation et marquée pour l'exportation à l'environnement de les commandes ultérieures.

et ceci aussi:

en utilisant " + "plutôt que" - " provoque ces options pour être désactivé. Le les options peuvent également être utilisées lors de l'invocation du shell. L'ensemble actuel des options peuvent être trouvés dans $-.

10
répondu Nagev 2017-03-08 11:46:05

améliorer la réponse de Silas Paul

exporter les variables sur un sous-puits les rend locales à la commande.

(export $(cat .env | xargs) && rails c)

9
répondu Jaydeep 2015-10-21 20:37:00

plus simple:

  1. extraire le contenu du fichier
  2. supprimer toutes les lignes vides (juste incase vous avez séparé quelques trucs)
  3. supprimer tous les commentaires (juste incase vous avez ajouté certains...)
  4. ajouter export à toutes les lignes
  5. eval le tout

eval $(cat .env | sed -e /^$/d -e /^#/d -e 's/^/export /')

une autre option (vous ne je dois lancer eval (merci à @Jaydeep)):

export $(cat .env | sed -e /^$/d -e /^#/d | xargs)

enfin, si vous voulez rendre votre vie vraiment facile, ajoutez ceci à votre ~/.bash_profile :

function source_envfile() { export $(cat | sed -e /^$/d -e /^#/d | xargs); }

(ASSUREZ-VOUS DE RECHARGER VOS PARAMÈTRES DE BASH!!! source ~/.bash_profile ou.. il suffit de faire un nouvel onglet / Fenêtre et Problème résolu) vous l'appelez comme ceci: source_envfile .env

8
répondu Javier Buzzi 2017-11-28 12:36:23

vous pouvez utiliser votre script original pour définir les variables, mais vous devez l'appeler de la manière suivante (avec un point autonome):

. ./minientrega.sh

il pourrait également y avoir un problème avec l'approche cat | while read . Je vous recommande d'utiliser l'approche while read line; do .... done < $FILE .

voici un exemple pratique:

> cat test.conf
VARIABLE_TMP1=some_value

> cat run_test.sh
#/bin/bash
while read line; do export "$line";
done < test.conf
echo "done"

> . ./run_test.sh
done

> echo $VARIABLE_TMP1
some_value
5
répondu Extrapolator 2015-09-11 19:49:53

en S'appuyant sur d'autres réponses, voici une façon d'exporter seulement un sous-ensemble de lignes dans un fichier, y compris des valeurs avec des espaces comme PREFIX_ONE="a word" :

set -a
. <(grep '^[ ]*PREFIX_' conf-file)
set +a
5
répondu Victor Roetman 2017-03-09 00:44:25

j'ai des problèmes avec les solutions proposées:

  • la solution de @anubhava rend l'écriture de fichiers de configuration conviviaux très ennuyeuse très rapide, et aussi - vous ne voudrez peut-être pas toujours exporter votre configuration.
  • @Silas Paul solution casse quand vous avez des variables qui ont des espaces ou d'autres caractères qui fonctionnent bien dans les valeurs citées, mais $() fait un gâchis de.

Voici ma solution, qui est encore assez terrible IMO - et ne résout pas le problème "exporter seulement à un enfant" abordé par Silas (bien que vous pouvez probablement l'exécuter dans un sous-shell pour limiter la portée):

source .conf-file
export $(cut -d= -f1 < .conf-file)
1
répondu Guss 2015-01-28 09:53:19

espaces blancs dans la valeur

il y a beaucoup de grandes réponses ici, mais je les ai trouvées toutes sans soutien pour l'espace blanc dans la valeur:

DATABASE_CLIENT_HOST=host db-name db-user 0.0.0.0/0 md5

j'ai trouvé 2 solutions qui fonctionnent avec de telles valeurs avec le soutien des lignes vides et des commentaires.

un basé sur sed et @javier-buzzi réponse :

source <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x "&"/g' .env)

et un avec la ligne de lecture dans une boucle basée sur @john1024 réponse

while read -r line; do declare -x "$line"; done < <(egrep -v "(^#|^\s|^$)" .env)

la clé ici est d'utiliser declare -x et de mettre la ligne entre guillemets. Je ne sais pas pourquoi, mais quand vous reformatez le code boucle en plusieurs lignes cela ne marchera pas - Je ne suis pas un programmeur de bash, j'ai juste bricolé ensemble ceux-ci, c'est encore magique pour moi:)

1
répondu Janusz Skonieczny 2018-04-11 06:52:43

si vous obtenez une erreur parce qu'une de vos variables contient une valeur qui contient des espaces blancs, vous pouvez essayer de réinitialiser IFS (séparateur de champ interne) de bash en \n pour laisser bash interpréter cat .env comme une liste de paramètres pour l'exécutable env .

exemple:

IFS=$'\n'; env $(cat .env) rails c

voir aussi:

0
répondu Giovanni Cappellotto 2017-04-13 12:36:28

Si vous voulez charger votre .env fichier dans le processus d'exécution à L'intérieur de Visual Studio code, vous pouvez ajouter une référence à votre .fichier env dans votre launch.json en utilisant la envFile propriété:

"configurations": [
    {
        "name": "Launch server.js with .env",
        "type": "node",
        "request": "launch",
        "envFile": "${workspaceRoot}/.env",
        ...
    }
]
0
répondu maxpaj 2018-08-09 13:10:31

je suis tombé sur ce fil quand j'ai essayé de réutiliser Docker --env-file s dans un shell. leur format n'est pas compatible bash mais il est simple: name=value , pas de citation, pas de substitution. Ils ignorent également les lignes vierges et les commentaires # .

Je ne pouvais pas tout à fait l'obtenir compatible posix, Mais voici un qui devrait fonctionner dans des coquilles de type bash (testé en zsh sur OSX 10.12.5 et bash sur Ubuntu 14.04):

while read -r l; do export "$(sed 's/=.*$//' <<<$l)"="$(sed -E 's/^[^=]+=//' <<<$l)"; done < <(grep -E -v '^\s*(#|$)' your-env-file)

Il ne sera pas gérer trois cas dans l'exemple de la doc ci-dessus:

  • bash: export: `123qwe=bar': not a valid identifier
  • bash: export: `org.spring.config=something': not a valid identifier
  • et il ne traitera pas la syntaxe de passage (un nu FOO )
-1
répondu Bob Zoller 2017-06-23 20:55:25

My .env:

#!/bin/bash
set -a # export all variables

#comments as usual, this is a bash script
USER=foo
PASS=bar

set +a #stop exporting variables

invoquant:

source .env; echo $USER; echo $PASS

référence https://unix.stackexchange.com/questions/79068/how-to-export-variables-that-are-set-all-at-once

-3
répondu Tudor Ilisoi 2018-05-19 19:40:45