1149 Stimmen

Set Umgebungsvariablen aus einer Datei mit Paaren von Schlüssel/Wert.

TL;DR: Wie exportiere ich einen Satz von Schlüssel/Wert-Paaren aus einer Textdatei in die Shell-Umgebung?


Zur Information, hier ist die ursprüngliche Version der Frage mit Beispielen.

Ich schreibe ein Skript in bash, das Dateien mit 3 Variablen in einem bestimmten Ordner analysiert, dies ist eine davon:

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

Diese Datei ist in ./conf/prac1 gespeichert

Mein Skript minientrega.sh analysiert die Datei dann mit diesem Code:

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

Aber wenn ich minientrega.sh prac1 in der Befehlszeile ausführe, werden die Umgebungsvariablen nicht gesetzt

Ich habe auch versucht, source ./conf/$1 zu verwenden, aber das gleiche Problem tritt immer noch auf

Vielleicht gibt es einen anderen Weg, dies zu tun, ich muss einfach die Umgebungsvariablen der Datei verwenden, die ich als Argument meines Skripts übergebe.

52voto

gsf Punkte 1658

Die allexport-Option wird in einigen anderen Antworten hier erwähnt, für die set -a die Abkürzung ist. Das Einbinden der .env ist wirklich besser als das Schleifen über Zeilen und Exportieren, da es Kommentare, leere Zeilen und sogar von Befehlen generierte Umgebungsvariablen ermöglicht. Meine .bashrc enthält folgendes:

# Laden der .env in der Shell
dotenv () {
  set -a
  [ -f .env ] && . .env
  set +a
}

# Führe dotenv beim Anmelden aus
dotenv

# Führe dotenv bei jedem neuen Verzeichnis aus
cd () {
  builtin cd $@
  dotenv
}

43voto

kolypto Punkte 26888

Das Problem mit source besteht darin, dass die Datei eine korrekte Bash-Syntax haben muss und einige Sonderzeichen sie ruinieren werden: =, ", ', <, > und andere. In einigen Fällen können Sie also einfach

source development.env

und es wird funktionieren.

Diese Version hingegen hält jedes Sonderzeichen in Werten stand:

set -a
source <(cat development.env | \
    sed -e '/^#/d;/^\s*$/d' -e "s/'/'\\\''/g" -e "s/=\(.*\)/='\1'/g")
set +a

Erklärung:

  • -a bedeutet, dass jede Bash-Variable zu einer Umgebungsvariable wird
  • /^#/d entfernt Kommentare (Zeichenfolgen, die mit # beginnen)
  • /^\s*$/d entfernt leere Zeichenfolgen, einschließlich Leerzeichen
  • "s/'/'\\\''/g" ersetzt jedes einfache Anführungszeichen durch '\'', was eine Tricksequenz in Bash ist, um ein Anführungszeichen zu erzeugen :)
  • "s/=\(.*\)/='\1'/g" wandelt jedes a=b in a='b' um

Als Ergebnis können Sie Sonderzeichen verwenden :)

Um diesen Code zu debuggen, ersetzen Sie source durch cat und Sie werden sehen, was dieser Befehl produziert.


Hinweis für direnv-Benutzer: Es gibt eine Hilfsfunktion dotenv, verwenden Sie sie stattdessen in Ihrer .envrc-Datei:

[ -f ".env" ] && dotenv ".env"

34voto

selvan Punkte 1198
eval $(cat .env | sed 's/^/export /')

27voto

tutuDajuju Punkte 9537

Hier ist eine weitere sed Lösung, die kein eval ausführt oder ruby erfordert:

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

Dies fügt export hinzu und behält Kommentare in Zeilen, die mit einem Kommentar beginnen.

Inhalt der .env

A=1
#B=2

Beispiel-Durchlauf

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

Ich fand dies besonders nützlich beim Konstruieren einer solchen Datei zum Laden in einer systemd Unit-Datei, mit EnvironmentFile.

23voto

Jules Colle Punkte 10421

Nicht genau sicher warum oder was ich verpasst habe, aber nachdem ich die meisten Antworten durchlaufen habe und gescheitert bin, habe ich festgestellt, dass ich mit dieser .env-Datei:

MY_VAR="hallo!"
MY_OTHER_VAR=123

Einfach folgendes tun könnte:

source .env
echo $MY_VAR

Ausgabe: Hallo!

Scheint in Ubuntu Linux einwandfrei zu funktionieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X