TL; DR: Comment exporter un ensemble de paires clé / valeur d'un fichier texte dans l'environnement shell?
Pour mémoire, voici la version originale de la question, avec des exemples.
J'écris un script en bash qui analyse des fichiers avec 3 variables dans un certain dossier, c'est l'un d'entre eux:
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 analyse ensuite le fichier en utilisant ce code:
cat ./conf/$1 | while read line; do
export $line
done
Mais quand j'exécute minientrega.sh prac1
dans la ligne de commande, cela ne définit pas les variables d'environnement
J'ai également essayé d'utiliser source ./conf/$1
mais le même problème s'applique toujours
Peut-être qu'il y a une autre façon de le faire, j'ai juste besoin d'utiliser les variables d'environnement du fichier que je passe comme argument de mon script.
la source
Réponses:
Le problème avec votre approche est que
export
lawhile
boucle se produit dans un sous-shell, et ces variables ne seront pas disponibles dans le shell actuel (shell parent de la boucle while).Ajouter une
export
commande dans le fichier lui-même:Ensuite, vous devez source dans le fichier dans le shell actuel en utilisant:
OU
la source
export
n'est pas idéal, le problème peut également être résolu en utilisant la redirection d'entrée simplement sur la boucle:while read line; do ... ; done < ./conf/$1
.< <(commands that generate output)
set -o allexport
export
le romprait pour des choses comme Java, SystemD ou d'autres outilsawk '{print "export " $0}' envfile
commande de commodité pour ajouter l'exportation au début de chaque ligneCela pourrait être utile:
La raison pour laquelle j'utilise ceci est si je veux tester des
.env
trucs dans ma console de rails.gabrielf a trouvé un bon moyen de garder les variables locales. Cela résout le problème potentiel lors du passage d'un projet à l'autre.
Je l'ai testé avec
bash 3.2.51(1)-release
Mise à jour:
Pour ignorer les lignes commençant par
#
, utilisez ceci (grâce au commentaire de Pete ):Et si vous voulez
unset
toutes les variables définies dans le fichier, utilisez ceci:Mise à jour:
Pour gérer également des valeurs avec des espaces, utilisez:
sur les systèmes GNU - ou:
sur les systèmes BSD.
la source
export $(cat .env)
mais je ne sais pas comment gérer les espaces.-d
pour définir le délimiteur, donc j'essaieenv $(cat .env | xargs -d '\n') rails
, mais il reste des erreurs avec un fichier introuvable s'il.env
a des espaces. Une idée pourquoi cela ne fonctionne pas?eval $(cat .env) rails
-o allexport
permet d'exporter toutes les définitions de variables suivantes.+o allexport
désactive cette fonction.la source
.env
fichier contient des commentaires. Merci!set -o allexport; source conf-file; set +o allexport
set -a; . conf-file; set +a
.Si
env.txt
c'est comme:Explications -a est équivalent à allexport . En d'autres termes, chaque affectation de variable dans le shell est exportée dans l'environnement (pour être utilisée par plusieurs processus enfants). Plus d'informations peuvent être trouvées dans la documentation intégrée de Set :
la source
-a
est équivalent àallexport
. En d'autres termes, chaque affectation de variable dans le shell estexport
éditée dans l'environnement (pour être utilisée par plusieurs processus enfants). Voir également cet article gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlL'
allexport
option est mentionnée dans quelques autres réponses ici, dontset -a
le raccourci. L'acquisition du .env est vraiment meilleure que la boucle sur les lignes et l'exportation, car elle permet les commentaires, les lignes vides et même les variables d'environnement générées par les commandes. Mon .bashrc comprend les éléments suivants:la source
VAR=
.la source
eval $(cat .env | sed 's/^[^$]/export /')
vous permet d'avoir des lignes vides pour une meilleure lisibilité.cat .env | sed 's/^[^$]/export /'
supprime le caractère initial. C'est à dire pour un fichierA=foo\nB=bar\n
que j'obtiensexport =foo\nexport =bar\n
. Cela fonctionne mieux pour sauter des lignes vides:cat .env | sed '/^$/! s/^/export /'
.cat
dans les deux cas: çaeval $(sed 's/^/export /' .env)
marche aussi bien.)J'ai trouvé que le moyen le plus efficace est:
Explication
Lorsque nous avons un
.env
fichier comme celui-ci:courir
xargs < .env
obtiendrakey=val foo=bar
nous allons donc obtenir un
export key=val foo=bar
et c'est exactement ce dont nous avons besoin!Limitation
la source
env
produire ce format.Voici une autre
sed
solution, qui n'exécute pas eval ou ne nécessite pas de rubis:Cela ajoute l'exportation, en gardant les commentaires sur les lignes commençant par un commentaire.
Contenu .env
échantillon
J'ai trouvé cela particulièrement utile lors de la construction d'un tel fichier pour le chargement dans un fichier d'unité systemd, avec
EnvironmentFile
.la source
J'ai surévalué la réponse de user4040650 car elle est à la fois simple et permet les commentaires dans le fichier (c'est-à-dire les lignes commençant par #), ce qui est très souhaitable pour moi, car des commentaires expliquant les variables peuvent être ajoutés. Réécriture dans le contexte de la question d'origine.
Si le script est appelé comme indiqué
minientrega.sh prac1
:, alors minientrega.sh pourrait avoir:Ce qui suit a été extrait de la documentation de l' ensemble :
Et cela aussi:
la source
Améliorer la réponse de Silas Paul
l'exportation des variables sur un sous-shell les rend locales à la commande.
(export $(cat .env | xargs) && rails c)
la source
(set -a; source dev.env; set +a; rails c)
pour bénéficier également des avantages de l'approvisionnement (par exemple, le script peut s'exécuter).SAVE=$(set +o | grep allexport) && set -o allexport && . .env; eval "$SAVE"
Cela permettra de sauvegarder / restaurer vos options d'origine, quelles qu'elles soient.
L'utilisation
set -o allexport
a l'avantage de sauter correctement les commentaires sans regex.set +o
en lui-même génère toutes vos options actuelles dans un format que bash pourra exécuter ultérieurement. Aussi pratique:set -o
en lui-même, génère toutes vos options actuelles dans un format convivial.la source
exec env -i bash
effacer l'environnement existant avant d'appelereval
si vous avez besoin de désactiver les variables qui ne sont définies qu'à l'intérieur.env
.Le moyen le plus court que j'ai trouvé:
Votre
.env
dossier:Alors juste
Bonus: Parce que c'est un court liner, il est très utile dans le
package.json
fichierla source
VARIABLE_NAME="A_VALUE"
Plus simple:
export
à toutes les ligneseval
le touteval $(cat .env | sed -e /^$/d -e /^#/d -e 's/^/export /')
Une autre option (vous n'avez pas à exécuter
eval
(grâce à @Jaydeep)):Enfin, si vous voulez vraiment vous faciliter la vie, ajoutez ceci à votre
~/.bash_profile
:function source_envfile() { export $(cat $1 | sed -e /^$/d -e /^#/d | xargs); }
(ASSUREZ-VOUS DE RECHARGER VOS PARAMÈTRES DE BASH !!!
source ~/.bash_profile
ou .. faites simplement un nouvel onglet / fenêtre et le problème est résolu) vous l'appelez comme ceci:source_envfile .env
la source
source <( echo $(sed -E -n 's/[^#]+/ &/ p' <(echo "${2}" | tr -d '\r')) );
. D'une manière ou d'une autre, gitlab enregistre la variable secrète avec un retour chariot Windows, j'ai donc dû le couper avectr -d '\r'
.Vous pouvez utiliser votre script d'origine pour définir les variables, mais vous devez l'appeler de la manière suivante (avec un point autonome):
Il pourrait également y avoir un problème avec l'
cat | while read
approche. Je recommanderais d'utiliser l'approchewhile read line; do .... done < $FILE
.Voici un exemple de travail:
la source
test.conf
tant que fichier de script. Cela le rend meilleur. Il est plus sûr de ne pas autoriser les scripts sauf si vous en avez réellement besoin, surtout si quelqu'un ne se rend pas compte que c'est ce qui se passe (ou oublie).En s'appuyant sur d'autres réponses, voici un moyen d'exporter uniquement un sous-ensemble de lignes dans un fichier, y compris des valeurs avec des espaces comme
PREFIX_ONE="a word"
:la source
Voici ma variante:
par rapport aux solutions précédentes:
.env
ne sont pas exposées à l'appelant)set
optionsset -a
.
au lieu d'source
éviter le bashisme.env
chargement échouela source
set -a && . ./.env && "$@" && echo "your comand here"
Je travaille avec docker-compose et des
.env
fichiers sur Mac, et.env
je voulais importer le dans mon shell bash (pour les tests), et la "meilleure" réponse ici était de trébucher sur la variable suivante:.env
Solution
J'ai donc fini par utiliser
eval
et encapsuler mes définitions de var env dans des guillemets simples.Version bash
la source
Mon .env:
Invoquant:
Référence /unix/79068/how-to-export-variables-that-are-set-all-at-once
la source
J'ai des problèmes avec les solutions suggérées précédemment:
$()
qui gâchent tout.Voici ma solution, qui est encore assez terrible IMO - et ne résout pas le problème "exporter seulement vers un enfant" résolu par Silas (bien que vous puissiez probablement l'exécuter dans un sous-shell pour limiter la portée):
la source
Mes exigences étaient:
export
préfixe (pour compatibilité avec dotenv)Version de travail complète compilée à partir des réponses ci-dessus:
la source
Tout d'abord, créez un fichier d'environnement qui aura toute la paire clé-valeur des environnements comme ci-dessous et nommez-le comme vous voulez dans mon cas, son
env_var.env
Ensuite, créez un script qui exportera toutes les variables d'environnement pour l'environnement python comme ci-dessous et nommez-le comme
export_env.sh
Ce script prendra le premier argument comme fichier d'environnement, puis exportera toutes les variables d'environnement dans ce fichier et exécutera ensuite la commande.
USAGE:
la source
Je suis tombé sur ce fil lorsque j'essayais de réutiliser Docker
--env-file
dans un shell. Leur format n'est pas compatible bash mais il est simple:name=value
pas de guillemets, pas de substitution. Ils ignorent également les lignes vides et les#
commentaires.Je ne pouvais pas vraiment le rendre compatible posix, mais en voici un qui devrait fonctionner dans des shells de type bash (testé en zsh sur OSX 10.12.5 et bash sur Ubuntu 14.04):
Il ne traitera pas trois cas dans l'exemple des documents liés ci-dessus:
bash: export: `123qwe=bar': not a valid identifier
bash: export: `org.spring.config=something': not a valid identifier
FOO
)la source
Espaces blancs dans la valeur
Il y a beaucoup de bonnes réponses ici, mais je les ai toutes trouvées manquant de support pour l'espace blanc dans la valeur:
J'ai trouvé 2 solutions qui fonctionnent avec de telles valeurs avec le support des lignes vides et des commentaires.
Une réponse basée sur sed et @ javier-buzzi :
Et une avec une ligne de lecture dans une boucle basée sur la réponse @ john1024
La clé ici est d'utiliser
declare -x
et de mettre la ligne entre guillemets. Je ne sais pas pourquoi, mais lorsque vous reformatez le code de la boucle sur plusieurs lignes, cela ne fonctionnera pas - je ne suis pas un programmeur bash, je les ai simplement engloutis, c'est toujours magique pour moi :)la source
sed
solution pour qu'elle fonctionne. Mais d'abord une explication:-e
est l'abréviation de--expression
, qui indique simplementsed
les opérations à effectuer.-e /^$/d
supprime les lignes vides de la sortie (pas le fichier).-e /^#/d
supprime les commentaires bash (lignes commençant par #) de la sortie.'s/.*/declare -x "&"/g'
remplace (substitue) les lignes restantes pardeclare -x "ENV_VAR="VALUE""
. Lorsque vous vous procurez cela, du moins pour moi, cela n'a pas fonctionné. Au lieu de cela, j'ai dû utilisersource <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x &/g' .env)
, pour retirer l'"
emballage supplémentaire .ENV_VAR="lorem ipsum"
, j'aiENV_VAR=lorem ipsum
, sans guillemets dans le fichier .env. Maintenant, je ne sais pas pourquoi, mais c'était probablement problématique dans d'autres outils qui analysent ce fichier. Et au lieu delorem ipsum
j'ai terminé avec la"lorem ipsum"
valeur - avec des guillemets. Merci pour les explications :)ENV_VAR="lorem ipsum"
plus. Dans mon cas d'utilisation, mon hébergeur génère ce fichier en fonction de certaines options de configuration que j'ai définies et insère les guillemets doubles. Donc, je suis obligé de contourner cela. Merci pour votre aide ici - m'a fait gagner beaucoup de temps à essayer de trouver les bonnessed
options moi-même!essayez quelque chose comme ça
la source
Comment ça fonctionne
.env
fichier. Toutes les variables seront exportées dans l'environnement actuel.declare -x VAR="val"
qui exporterait chacune des variables dans l'environnement.Caractéristiques
.env
peut avoir des commentaires.env
peut avoir des lignes vides.env
ne nécessite pas d'en-tête ou de pied de page spécial comme dans les autres réponses (set -a
etset +a
).env
ne nécessite pas d'avoirexport
pour chaque valeurla source
Si vous obtenez une erreur car l'une de vos variables contient une valeur qui contient des espaces blancs, vous pouvez essayer de réinitialiser bash
IFS
(séparateur de champ interne)\n
pour laisser bash interpréter lecat .env
résultat comme une liste de paramètres pour l'env
exécutable.Exemple:
Voir également:
la source
Mon fichier .env ressemble à:
En utilisant les méthodes de @henke , la valeur exportée finit par contenir les guillemets
"
Mais je veux que la valeur exportée ne contienne que:
Pour y remédier, je modifie la commande pour supprimer les guillemets:
la source
Celui-ci fait face aux espaces sur le RHS et saute les variables `` étranges '' telles que les définitions de module bash (avec `` () ''):
la source