Legen Sie Umgebungsvariablen aus einer Datei mit Schlüssel / Wert-Paaren fest

512

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


Im Folgenden finden Sie die Originalversion 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 wird in ./conf/prac1 gespeichert

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

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

Wenn ich jedoch minientrega.sh prac1in der Befehlszeile ausführe , werden die Umgebungsvariablen nicht festgelegt

Ich habe auch versucht, source ./conf/$1aber das gleiche Problem gilt immer noch

Vielleicht gibt es eine andere Möglichkeit, dies zu tun. Ich muss nur die Umgebungsvariablen der Datei verwenden, die ich als Argument für mein Skript übergebe.

hugo19941994
quelle
Gleiches gilt für Unix: unix.stackexchange.com/questions/31797/…
Ciro Santilli 法轮功 冠状 病 六四 事件 19
Gleiches gilt für Ruby: stackoverflow.com/questions/2139080/… , ein Juwel, das es schafft: github.com/bkeepers/dotenv
Ciro Santilli 法轮功 冠状 病 六四 事件 19
Dies ist eine großartige Frage, die jedoch viel zu spezifisch formuliert ist, mit bestimmten Variablennamen ("MINIENTREGA_FECHALIMITE"? Was bedeutet das?) Und Zahlen (3). Die allgemeine Frage lautet einfach: "Wie exportiere ich eine Reihe von Schlüssel / Wert-Paaren aus einer Textdatei in die Shell-Umgebung?"
Dan Dascalescu
Auch dies wurde bereits unter unix.SE beantwortet und ist dort wohl eher themenbezogen .
Dan Dascalescu

Antworten:

208

Das Problem bei Ihrem Ansatz ist, dass die exportIn-the- whileLoop in einer Sub-Shell stattfindet und diese Variablen in der aktuellen Shell (übergeordnete Shell der while-Schleife) nicht verfügbar sind.

In exportBefehl in der Datei selbst:

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

Dann müssen Sie die Datei in der aktuellen Shell mit folgenden Quellen versehen:

. ./conf/prac1

ODER

source ./conf/prac1
Anubhava
quelle
4
Obwohl exportes nicht ideal ist, die Datei Zeile für Zeile zu lesen und jede Zeile an zu übergeben , kann das Problem auch behoben werden, indem einfach die Umleitung der Eingabe in der Schleife verwendet wird : while read line; do ... ; done < ./conf/$1.
Chepner
4
Und wenn es nicht aus einer Datei ist, verwenden Sie< <(commands that generate output)
o11c
5
Sie haben eine sauberere Lösung , ich habe eine Vorliebe fürset -o allexport
Heralight
2
Wenn Sie diese .env-Datei zwischen Systemen verwenden, wird sie durch Einfügen exportfür Java, SystemD oder andere Tools
beschädigt
1
awk '{print "export " $0}' envfileBequemlichkeitsbefehl, um den Export an den Anfang jeder Zeile zu stellen
Shardj
887

Dies könnte hilfreich sein:

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

Der Grund, warum ich dies verwende, ist, wenn ich .envDinge in meiner Rails-Konsole testen möchte .

gabrielf hat einen guten weg gefunden, um die variablen lokal zu halten. Dies löst das potenzielle Problem beim Übergang von Projekt zu Projekt.

env $(cat .env | xargs) rails

Ich habe das mit getestet bash 3.2.51(1)-release


Aktualisieren:

#Verwenden Sie Folgendes, um Zeilen zu ignorieren, die mit beginnen (dank Petes Kommentar ):

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

Wenn Sie unsetalle in der Datei definierten Variablen verwenden möchten , verwenden Sie Folgendes:

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

Aktualisieren:

Verwenden Sie Folgendes, um Werte auch mit Leerzeichen zu behandeln:

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

auf GNU-Systemen - oder:

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

auf BSD-Systemen.

Silas Paul
quelle
6
Vielen Dank, ich finde es gut, dass der Datei nichts vorangestellt werden muss - dies ermöglicht die Kompatibilität mit dem .env-Format von Foreman (Procfile).
Natevw
29
Ich kam mit der Lösung: env $ (cat .env | xargs) Schienen
gabrielf
4
Dies scheint nicht zu funktionieren, wenn einer der env-Werte Leerzeichen enthält, obwohl ich nicht sicher bin, wie Werte mit Leerzeichen am besten / gewünscht angegeben werden können. github.com/ddollar/foreman/issues/56 sagt, es sollte funktionieren, export $(cat .env)aber ich weiß nicht, wie ich mit Leerzeichen umgehen soll.
Dan Benamy
6
@BenjaminWheeler GNU Linux hat -dzum Setzen des Trennzeichens, also versuche ich es env $(cat .env | xargs -d '\n') rails, aber es gibt immer noch Fehler mit einer Datei, die nicht gefunden wurde, wenn .envLeerzeichen vorhanden sind. Irgendeine Idee, warum das nicht funktioniert?
Bailey Parker
19
Hier ist eine kürzere Varianteeval $(cat .env) rails
Manalang
412

-o allexportErmöglicht den Export aller folgenden Variablendefinitionen. +o allexportDeaktiviert diese Funktion.

set -o allexport
source conf-file
set +o allexport
user4040650
quelle
9
Klappt wunderbar! Auch wenn die .envDatei Kommentare enthält. Vielen Dank!
Slava Fomin II
9
Und in einer Zeileset -o allexport; source conf-file; set +o allexport
HarlemSquirrel
1
Dies ist eine großartige Möglichkeit, eine Eigenschaftendatei einzulesen, wenn das Jenkins EnvInject-Plug-In nicht funktioniert. Vielen Dank!
Teresa Peters
21
@CMCDragonkai, für POSIX wäre es set -a; . conf-file; set +a.
Charles Duffy
3
Diese Methode funktioniert, wenn die Umgebungsvariablen Leerzeichen enthalten. Viele der anderen nicht. Während die eval () -Methode dies tut, werde ich auch ein wenig verrückt, wenn ich eval
CommandZ
138
set -a
. ./env.txt
set +a

Wenn env.txtist wie:

VAR1=1
VAR2=2
VAR3=3
...

Erklärungen -a entspricht allexport . Mit anderen Worten, jede Variablenzuweisung in der Shell wird in die Umgebung exportiert (zur Verwendung durch mehrere untergeordnete Prozesse). Weitere Informationen finden Sie in der Dokumentation zum Set :

-a     Jede Variable oder Funktion, die erstellt oder geändert wird, erhält das Exportattribut und wird für den Export nachfolgender Befehle in die Umgebung markiert.

Wenn Sie '+' anstelle von '-' verwenden, werden diese Optionen deaktiviert. Die Optionen können auch beim Aufruf der Shell verwendet werden. Die aktuellen Optionen finden Sie in $ -.

Dan Kowalczyk
quelle
Können Sie die -a und + a erklären?
Otto
11
@Otto -aentspricht allexport. Mit anderen Worten, jede Variablenzuweisung in der Shell wird exportin die Umgebung eingearbeitet (zur Verwendung durch mehrere untergeordnete Prozesse). Siehe auch diesen Artikel gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
Dan Kowalczyk
33

Die allexportOption wird hier in einigen anderen Antworten erwähnt, für die set -adie Verknüpfung gilt. Die Beschaffung der .env-Datei ist wirklich besser als das Durchlaufen von Zeilen und das Exportieren, da Kommentare, Leerzeilen und sogar Umgebungsvariablen, die von Befehlen generiert werden, berücksichtigt werden. Meine .bashrc enthält Folgendes:

# .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
}
gsf
quelle
3
Das sieht gut aus, aber entladen Sie Umgebungsvariablen, wenn Sie das Verzeichnis verlassen?
Bastian Venthur
1
Ich habe keine Variablen deaktiviert und es war nie ein Problem. Meine Apps verwenden in der Regel unterschiedliche Variablennamen. Wenn es Überschneidungen gibt, setze ich sie in dieser .env mit leer VAR=.
gsf
26
eval $(cat .env | sed 's/^/export /')
Selvan
quelle
1
Mit eval $(cat .env | sed 's/^[^$]/export /')können Sie Leerzeilen verwenden, um die Lesbarkeit zu verbessern.
Mario Uher
2
Ich finde, das cat .env | sed 's/^[^$]/export /'entfernt den ursprünglichen Charakter. Dh für eine Datei, die A=foo\nB=bar\nich bekomme export =foo\nexport =bar\n. Dies funktioniert besser zum Überspringen von Leerzeilen : cat .env | sed '/^$/! s/^/export /'.
Owen S.
(Ich stelle auch für UNIX-Code-Golfer fest, dass Sie catin beiden Fällen nicht benötigen : eval $(sed 's/^/export /' .env)funktioniert genauso gut.)
Owen S.
21

Ich fand den effizientesten Weg ist:

export $(xargs < .env)

Erläuterung

Wenn wir eine .envDatei wie diese haben:

key=val
foo=bar

laufen xargs < .envwird bekommenkey=val foo=bar

Also werden wir eine bekommen export key=val foo=barund es ist genau das, was wir brauchen!

Verjährung

  1. Fälle, in denen die Werte Leerzeichen enthalten, werden nicht behandelt. Befehle wie env erzeugen dieses Format. - @Shardj
Huan
quelle
3
Fälle, in denen die Werte Leerzeichen enthalten, werden nicht behandelt. Befehle wie enverzeugen dieses Format.
Shardj
19

Hier ist eine andere sedLösung, die nicht ausgewertet wird oder Rubin benötigt:

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

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

.env Inhalt

A=1
#B=2

Probelauf

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

Ich fand dies besonders nützlich, wenn ich eine solche Datei zum Laden in eine systemd-Einheitendatei mit erstellteEnvironmentFile .

tutuDajuju
quelle
unterstützt nicht mehrere Zeilen in OSX
Abdennour TOUMI
17

Ich habe die Antwort von user4040650 positiv bewertet, da sie sowohl einfach ist als auch Kommentare in der Datei zulässt (dh Zeilen, die mit # beginnen), was für mich sehr wünschenswert ist, da Kommentare hinzugefügt werden können, in denen die Variablen erläutert werden. Einfach im Kontext der ursprünglichen Frage umschreiben.

Wenn das Skript wie angegeben aufgerufen wird : minientrega.sh prac1, könnte minientrega.sh Folgendes haben:

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

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

Folgendes wurde aus der Set-Dokumentation extrahiert :

Dieser Einbau ist so kompliziert, dass er einen eigenen Abschnitt verdient. Mit set können Sie die Werte von Shell-Optionen ändern und die Positionsparameter festlegen oder die Namen und Werte von Shell-Variablen anzeigen.

set [--abefhkmnptuvxBCEHPT] [-o Optionsname] [Argument…] set [+ abefhkmnptuvxBCEHPT] [+ o Optionsname] [Argument…]

Wenn keine Optionen oder Argumente angegeben werden, zeigt set die Namen und Werte aller Shell-Variablen und -Funktionen, sortiert nach dem aktuellen Gebietsschema, in einem Format an, das als Eingabe zum Festlegen oder Zurücksetzen der aktuell festgelegten Variablen wiederverwendet werden kann. Schreibgeschützte Variablen können nicht zurückgesetzt werden. Im POSIX-Modus werden nur Shell-Variablen aufgelistet.

Wenn Optionen angegeben werden, werden Shell-Attribute festgelegt oder deaktiviert. Optionen haben, falls angegeben, die folgenden Bedeutungen:

-a Jede Variable oder Funktion, die erstellt oder geändert wird, erhält das Exportattribut und wird für den Export nachfolgender Befehle in die Umgebung markiert.

Und das auch:

Wenn Sie '+' anstelle von '-' verwenden, werden diese Optionen deaktiviert. Die Optionen können auch beim Aufruf der Shell verwendet werden. Die aktuellen Optionen finden Sie in $ -.

Nagev
quelle
14

Verbesserung der Antwort von Silas Paul

Durch das Exportieren der Variablen in eine Subshell werden sie für den Befehl lokal.

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

Jaydeep Solanki
quelle
Dann können Sie dies nutzen, (set -a; source dev.env; set +a; rails c)um auch die Vorteile des Sourcing zu nutzen (z. B. kann das Skript ausgeführt werden).
Wacha
12

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

Dadurch werden Ihre ursprünglichen Optionen gespeichert / wiederhergestellt, unabhängig davon, um welche es sich handelt.

Die Verwendung set -o allexporthat den Vorteil, dass Kommentare ohne Regex ordnungsgemäß übersprungen werden.

set +oselbst gibt alle Ihre aktuellen Optionen in einem Format aus, das bash später ausführen kann. Auch praktisch: set -oAllein werden alle aktuellen Optionen in einem benutzerfreundlichen Format ausgegeben.

jwfearn
quelle
2
Ich würde wahrscheinlich exec env -i bashdie vorhandene Umgebung vor dem Aufruf löschen, evalwenn Sie Variablen deaktivieren müssen, die nur innerhalb festgelegt sind .env.
b4hand
11

Der kürzeste Weg, den ich gefunden habe:

Ihre .envDatei:

VARIABLE_NAME="A_VALUE"

Dann einfach

. ./.env && echo ${VARIABLE_NAME}

Bonus: Da es sich um einen kurzen Einzeiler handelt, ist er in package.jsonDateien sehr nützlich

  "scripts": {
    "echo:variable": ". ./.env && echo ${VARIABLE_NAME}"
  }
Flavien Volken
quelle
Wie wäre es, wenn Sie viele Variablen haben?
Madeo
@Madeo können Sie so viele Zeilen hinzufügen, wie Sie möchten, genauso wie die ZeileVARIABLE_NAME="A_VALUE"
Flavien Volken
9

Einfacher:

  1. Holen Sie sich den Inhalt der Datei
  2. Entfernen Sie alle leeren Zeilen (nur für den Fall, dass Sie einige Dinge getrennt haben).
  3. Entfernen Sie alle Kommentare (nur für den Fall, dass Sie einige hinzugefügt haben ...)
  4. exportzu allen Zeilen hinzufügen
  5. eval das ganze Ding

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

Eine weitere Option (Sie müssen nicht ausführen eval(dank @Jaydeep)):

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

Wenn Sie Ihr Leben WIRKLICH einfach gestalten möchten, fügen Sie Folgendes hinzu ~/.bash_profile:

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

(Stellen Sie sicher, dass Sie Ihre Bash-Einstellungen neu laden !!! source ~/.bash_profileoder ... erstellen Sie einfach einen neuen Tab / ein neues Fenster und lösen Sie das Problem.) Sie nennen es so:source_envfile .env

Javier Buzzi
quelle
2
Ich musste .env-Text aus der geheimen Variablen gitlab für eine Pipeline lesen: Basierend auf Ihrer Lösung funktionierte dieser Befehl für mich : source <( echo $(sed -E -n 's/[^#]+/ &/ p' <(echo "${2}" | tr -d '\r')) );. Irgendwie speichert gitlab die geheime Variable mit einem Windows-Wagenrücklauf, also musste ich das mit kürzen tr -d '\r'.
Metanerd
6

Sie können Ihr ursprüngliches Skript verwenden, um die Variablen festzulegen, aber Sie müssen es folgendermaßen aufrufen (mit eigenständigem Punkt):

. ./minientrega.sh

Es könnte auch ein Problem mit dem cat | while readAnsatz geben. Ich würde empfehlen, den Ansatz zu verwenden while read line; do .... done < $FILE.

Hier ist ein Arbeitsbeispiel:

> 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
Extrapolator
quelle
Im Gegensatz zu den meisten anderen Antworten wird diese Lösung nicht test.confals Skriptdatei ausgewertet. Das macht es besser. Es ist sicherer, Skripte nur dann zuzulassen, wenn Sie sie tatsächlich benötigen, insbesondere wenn jemand nicht merkt, dass dies der Fall ist (oder vergisst).
Meustrus
5

Aufbauend auf anderen Antworten können Sie hier nur eine Teilmenge von Zeilen in eine Datei exportieren, einschließlich Werte mit Leerzeichen wie PREFIX_ONE="a word":

set -a
. <(grep '^[ ]*PREFIX_' conf-file)
set +a
Victor Roetman
quelle
5

Hier ist meine Variante:

  with_env() {
    (set -a && . ./.env && "$@")
  }

verglichen mit den vorherigen Lösungen:

  • Es werden keine Variablen außerhalb des Gültigkeitsbereichs verloren (Werte von .envwerden dem Aufrufer nicht angezeigt)
  • macht keine Clobber- setOptionen
  • Gibt den Exit-Code des ausgeführten Befehls zurück
  • verwendet posix kompatibel set -a
  • verwendet .statt sourceBashismus zu vermeiden
  • Befehl wird nicht aufgerufen, wenn das .envLaden fehlschlägt
with_env rails console
Elan Ruusamäe
quelle
Sie können auch inline ausführen (die Variablen sind Ihrer aktuellen Terminalsitzung ausgesetzt): set -a && . ./.env && "$@" && echo "your comand here"
Giovanne Afonso
4

Ich arbeite mit Docker-Compose und .envDateien auf dem Mac und wollte diese .envin meine Bash-Shell importieren (zum Testen). Die "beste" Antwort hier war das Auslösen der folgenden Variablen:

.env

NODE_ARGS=--expose-gc --max_old_space_size=2048

Lösung

Also habe ich evalmeine env var defs verwendet und in einfache Anführungszeichen gesetzt.

eval $(grep -v -e '^#' .env | xargs -I {} echo export \'{}\')

Bash-Version

$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.
Nick Grealy
quelle
3

Meine .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

Aufrufen:

source .env; echo $USER; echo $PASS

Referenz /unix/79068/how-to-export-variables-that-are-set-all-at-once

Tudor Ilisoi
quelle
2

Ich habe Probleme mit den zuvor vorgeschlagenen Lösungen:

  • Die Lösung von @ anubhava macht das Schreiben von bash-freundlichen Konfigurationsdateien sehr schnell sehr ärgerlich, und außerdem möchten Sie Ihre Konfiguration möglicherweise nicht immer exportieren.
  • Die @ Silas Paul-Lösung bricht ab, wenn Sie Variablen mit Leerzeichen oder anderen Zeichen haben, die in Anführungszeichen gut funktionieren, aber $()ein Durcheinander daraus machen.

Hier ist meine Lösung, die IMO immer noch ziemlich schrecklich ist - und das von Silas angesprochene Problem "Nur an ein Kind exportieren" nicht löst (obwohl Sie es wahrscheinlich in einer Sub-Shell ausführen können, um den Umfang einzuschränken):

source .conf-file
export $(cut -d= -f1 < .conf-file)
Guss
quelle
2

Meine Anforderungen waren:

  • einfache .env-Datei ohne exportPräfixe (aus Kompatibilitätsgründen mit dotenv)
  • unterstützende Werte in Anführungszeichen: TEXT = "alpha bravo charlie"
  • unterstützende Kommentare mit dem Präfix # und Leerzeilen
  • Universal für Mac / BSD und Linux / GNU

Vollversion zusammengestellt aus den obigen Antworten:

  set -o allexport
  eval $(grep -v '^#' .env | sed 's/^/export /')
  set +o allexport
Alex
quelle
1
Was bringt "-o allexport", wenn Sie ihnen trotzdem "export" voranstellen?
il - ya
2

Erstellen Sie zunächst eine Umgebungsdatei, die alle Schlüssel-Wert-Paare der folgenden Umgebungen enthält, und benennen Sie sie in meinem Fall wie Sie möchten env_var.env

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

Erstellen Sie dann ein Skript, das alle Umgebungsvariablen für die Python-Umgebung wie unten exportiert und wie folgt benennt export_env.sh

#!/usr/bin/env bash

ENV_FILE="$1"
CMD=${@:2}

set -o allexport
source $ENV_FILE
set +o allexport

$CMD

Dieses Skript verwendet das erste Argument als Umgebungsdatei, exportiert dann alle Umgebungsvariablen in dieser Datei und führt anschließend den Befehl aus.

VERWENDUNGSZWECK:

./export_env.sh env_var.env python app.py
anand tripathi
quelle
1

Ich bin auf diesen Thread gestoßen, als ich versucht habe, Docker --env-filein einer Shell wiederzuverwenden . Ihr Format ist nicht bash-kompatibel, aber es ist einfach: name=valuekein Zitat, keine Substitution. Sie ignorieren auch Leerzeilen und# Kommentare.

Ich konnte es nicht ganz mit Posix kompatibel machen, aber hier ist eine, die in Bash-ähnlichen Shells funktionieren sollte (getestet in zsh unter OSX 10.12.5 und Bash unter Ubuntu 14.04):

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

Es wird nicht drei Fälle im Beispiel aus den oben verlinkten Dokumenten handhaben :

  • bash: export: `123qwe=bar': not a valid identifier
  • bash: export: `org.spring.config=something': not a valid identifier
  • und es wird nicht die Passthrough-Syntax verarbeiten (ein nackter FOO)
Bob Zoller
quelle
1

Leerzeichen im Wert

Hier gibt es viele gute Antworten, aber ich fand, dass sie alle keine Unterstützung für Leerzeichen im Wert haben:

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

Ich habe 2 Lösungen gefunden, die mit solchen Werten funktionieren und leere Zeilen und Kommentare unterstützen.

Eine basierend auf sed und @ javier-buzzi Antwort :

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

Und eine mit Lesezeile in einer Schleife basierend auf @ john1024 Antwort

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

Der Schlüssel hier liegt darin declare -x, Zeilen in doppelte Anführungszeichen zu setzen. Ich weiß nicht warum, aber wenn Sie den Schleifencode in mehrere Zeilen umformatieren, funktioniert er nicht - ich bin kein Bash-Programmierer, ich habe diese nur verschlungen, es ist immer noch magisch für mich :)

Janusz Skonieczny
quelle
1
Ich musste die sedLösung modifizieren , damit sie funktioniert. Aber zuerst eine Erklärung: -eist die Abkürzung für --expression, die nur sagt, sedwelche Operationen durchzuführen sind. -e /^$/dlöscht die leeren Zeilen aus der Ausgabe (nicht die Datei). -e /^#/dlöscht die Bash-Kommentare (Zeilen, die mit # beginnen) aus der Ausgabe. 's/.*/declare -x "&"/g'ersetzt (ersetzt) ​​die verbleibenden Zeilen durch declare -x "ENV_VAR="VALUE"". Wenn Sie dies, zumindest für mich, beschaffen, hat es nicht funktioniert. Stattdessen musste ich verwenden source <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x &/g' .env), um den zusätzlichen "Wrapper zu entfernen .
Jcasner
Ich benutze nicht ENV_VAR="lorem ipsum", ich habe ENV_VAR=lorem ipsum, ohne Anführungszeichen in der .env Datei. Jetzt bin ich mir nicht sicher warum, aber dies war wahrscheinlich in anderen Tools problematisch, die diese Datei analysieren. Und anstatt lorem ipsummit "lorem ipsum"Wert zu enden - mit Anführungszeichen. Danke für die Erklärungen :)
Janusz Skonieczny
1
Wenn es meine Wahl wäre, würde ich auch nicht verwenden ENV_VAR="lorem ipsum". In meinem Anwendungsfall generiert mein Hosting-Anbieter diese Datei basierend auf einigen von mir festgelegten Konfigurationsoptionen und fügt die doppelten Anführungszeichen ein. Also bin ich gezwungen, das zu umgehen. Vielen Dank für Ihre Hilfe hier - ich habe viel Zeit gespart, um die richtigen sedOptionen selbst zu finden!
Jcasner
1

versuche so etwas

for line in `cat your_env_file`; do if [[ $line != \#* ]];then export $line; fi;done
gaozhidf
quelle
1
t=$(mktemp) && export -p > "$t" && set -a && . ./.env && set +a && . "$t" && rm "$t" && unset t

Wie es funktioniert

  1. Erstellen Sie eine temporäre Datei.
  2. Schreiben Sie alle aktuellen Umgebungsvariablenwerte in die temporäre Datei.
  3. Aktivieren Sie den Export aller deklarierten Variablen im Quellenskript in die Umgebung.
  4. .envDatei lesen . Alle Variablen werden in die aktuelle Umgebung exportiert.
  5. Deaktivieren Sie den Export aller deklarierten Variablen im Quellenskript in die Umgebung.
  6. Lesen Sie den Inhalt der temporären Datei. Jede Zeile hätte, declare -x VAR="val"dass jede der Variablen in die Umgebung exportiert würde.
  7. Temporäre Datei entfernen.
  8. Deaktivieren Sie die Variable, die den temporären Dateinamen enthält.

Eigenschaften

  • Erhält die Werte der Variablen, die bereits in der Umgebung festgelegt wurden
  • .env kann Kommentare haben
  • .env kann leere Zeilen haben
  • .enverfordert keine spezielle Kopf- oder Fußzeile wie in den anderen Antworten ( set -aund set +a)
  • .envmuss nicht exportfür jeden Wert haben
  • Einzeiler
Alex Skrypnyk
quelle
0

Meine .env-Datei sieht folgendermaßen aus:

DATABASE_URI="postgres://sa:***@localhost:5432/my_db"
VARIABLE_1="SOME_VALUE"
VALIABLE_2="123456788"

Auf die @henke - Methode enthält der exportierte Wert die Anführungszeichen"

"postgres://sa:***@localhost:5432/my_db"
"SOME_VALUE"
"123456788"

Ich möchte jedoch, dass der exportierte Wert nur Folgendes enthält:

postgres://sa:***@localhost:5432/my_db
SOME_VALUE
123456788

Um das Problem zu beheben, bearbeite ich den Befehl zum Löschen der Anführungszeichen:

export $(grep -v '^#' dev.env | tr --delete '"' | xargs -d '\n')
Ricardo Yanez
quelle
0

Dieser behandelt Leerzeichen auf der rechten Seite und überspringt 'seltsame' Variablen wie Bash-Moduldefinitionen (mit '()' darin):

echo "# source this to set env vars" > $bld_dir/.env
env | while read line; do
    lhs="${line%%=*}"
    rhs="${line#*=}"
    if [[ "$lhs" =~ ^[0-9A-Za-z_]+$ ]]; then
        echo "export $lhs=\"$rhs\"" >> $bld_dir/.env
    fi
done
PatB
quelle