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 prac1
in der Befehlszeile ausführe , werden die Umgebungsvariablen nicht festgelegt
Ich habe auch versucht, source ./conf/$1
aber 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.
quelle
Antworten:
Das Problem bei Ihrem Ansatz ist, dass die
export
In-the-while
Loop in einer Sub-Shell stattfindet und diese Variablen in der aktuellen Shell (übergeordnete Shell der while-Schleife) nicht verfügbar sind.In
export
Befehl in der Datei selbst:Dann müssen Sie die Datei in der aktuellen Shell mit folgenden Quellen versehen:
ODER
quelle
export
es 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
.< <(commands that generate output)
set -o allexport
export
für Java, SystemD oder andere Toolsawk '{print "export " $0}' envfile
Bequemlichkeitsbefehl, um den Export an den Anfang jeder Zeile zu stellenDies könnte hilfreich sein:
Der Grund, warum ich dies verwende, ist, wenn ich
.env
Dinge 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.
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 ):Wenn Sie
unset
alle in der Datei definierten Variablen verwenden möchten , verwenden Sie Folgendes:Aktualisieren:
Verwenden Sie Folgendes, um Werte auch mit Leerzeichen zu behandeln:
auf GNU-Systemen - oder:
auf BSD-Systemen.
quelle
export $(cat .env)
aber ich weiß nicht, wie ich mit Leerzeichen umgehen soll.-d
zum Setzen des Trennzeichens, also versuche ich esenv $(cat .env | xargs -d '\n') rails
, aber es gibt immer noch Fehler mit einer Datei, die nicht gefunden wurde, wenn.env
Leerzeichen vorhanden sind. Irgendeine Idee, warum das nicht funktioniert?eval $(cat .env) rails
-o allexport
Ermöglicht den Export aller folgenden Variablendefinitionen.+o allexport
Deaktiviert diese Funktion.quelle
.env
Datei Kommentare enthält. Vielen Dank!set -o allexport; source conf-file; set +o allexport
set -a; . conf-file; set +a
.Wenn
env.txt
ist wie: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 :
quelle
-a
entsprichtallexport
. Mit anderen Worten, jede Variablenzuweisung in der Shell wirdexport
in die Umgebung eingearbeitet (zur Verwendung durch mehrere untergeordnete Prozesse). Siehe auch diesen Artikel gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlDie
allexport
Option wird hier in einigen anderen Antworten erwähnt, für dieset -a
die 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:quelle
VAR=
.quelle
eval $(cat .env | sed 's/^[^$]/export /')
können Sie Leerzeilen verwenden, um die Lesbarkeit zu verbessern.cat .env | sed 's/^[^$]/export /'
entfernt den ursprünglichen Charakter. Dh für eine Datei, dieA=foo\nB=bar\n
ich bekommeexport =foo\nexport =bar\n
. Dies funktioniert besser zum Überspringen von Leerzeilen :cat .env | sed '/^$/! s/^/export /'
.cat
in beiden Fällen nicht benötigen :eval $(sed 's/^/export /' .env)
funktioniert genauso gut.)Ich fand den effizientesten Weg ist:
Erläuterung
Wenn wir eine
.env
Datei wie diese haben:laufen
xargs < .env
wird bekommenkey=val foo=bar
Also werden wir eine bekommen
export key=val foo=bar
und es ist genau das, was wir brauchen!Verjährung
quelle
env
erzeugen dieses Format.Hier ist eine andere
sed
Lösung, die nicht ausgewertet wird oder Rubin benötigt:Dies fügt den Export hinzu und behält Kommentare in Zeilen bei, die mit einem Kommentar beginnen.
.env Inhalt
Probelauf
Ich fand dies besonders nützlich, wenn ich eine solche Datei zum Laden in eine systemd-Einheitendatei mit erstellte
EnvironmentFile
.quelle
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:Folgendes wurde aus der Set-Dokumentation extrahiert :
Und das auch:
quelle
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)
quelle
(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).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 allexport
hat den Vorteil, dass Kommentare ohne Regex ordnungsgemäß übersprungen werden.set +o
selbst gibt alle Ihre aktuellen Optionen in einem Format aus, das bash später ausführen kann. Auch praktisch:set -o
Allein werden alle aktuellen Optionen in einem benutzerfreundlichen Format ausgegeben.quelle
exec env -i bash
die vorhandene Umgebung vor dem Aufruf löschen,eval
wenn Sie Variablen deaktivieren müssen, die nur innerhalb festgelegt sind.env
.Der kürzeste Weg, den ich gefunden habe:
Ihre
.env
Datei:Dann einfach
Bonus: Da es sich um einen kurzen Einzeiler handelt, ist er in
package.json
Dateien sehr nützlichquelle
VARIABLE_NAME="A_VALUE"
Einfacher:
export
zu allen Zeilen hinzufügeneval
das ganze Dingeval $(cat .env | sed -e /^$/d -e /^#/d -e 's/^/export /')
Eine weitere Option (Sie müssen nicht ausführen
eval
(dank @Jaydeep)):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_profile
oder ... erstellen Sie einfach einen neuen Tab / ein neues Fenster und lösen Sie das Problem.) Sie nennen es so:source_envfile .env
quelle
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ürzentr -d '\r'
.Sie können Ihr ursprüngliches Skript verwenden, um die Variablen festzulegen, aber Sie müssen es folgendermaßen aufrufen (mit eigenständigem Punkt):
Es könnte auch ein Problem mit dem
cat | while read
Ansatz geben. Ich würde empfehlen, den Ansatz zu verwendenwhile read line; do .... done < $FILE
.Hier ist ein Arbeitsbeispiel:
quelle
test.conf
als 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).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"
:quelle
Hier ist meine Variante:
verglichen mit den vorherigen Lösungen:
.env
werden dem Aufrufer nicht angezeigt)set
Optionenset -a
.
stattsource
Bashismus zu vermeiden.env
Laden fehlschlägtquelle
set -a && . ./.env && "$@" && echo "your comand here"
Ich arbeite mit Docker-Compose und
.env
Dateien auf dem Mac und wollte diese.env
in meine Bash-Shell importieren (zum Testen). Die "beste" Antwort hier war das Auslösen der folgenden Variablen:.env
Lösung
Also habe ich
eval
meine env var defs verwendet und in einfache Anführungszeichen gesetzt.Bash-Version
quelle
Meine .env:
Aufrufen:
Referenz /unix/79068/how-to-export-variables-that-are-set-all-at-once
quelle
Ich habe Probleme mit den zuvor vorgeschlagenen Lösungen:
$()
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):
quelle
Meine Anforderungen waren:
export
Präfixe (aus Kompatibilitätsgründen mit dotenv)Vollversion zusammengestellt aus den obigen Antworten:
quelle
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
Erstellen Sie dann ein Skript, das alle Umgebungsvariablen für die Python-Umgebung wie unten exportiert und wie folgt benennt
export_env.sh
Dieses Skript verwendet das erste Argument als Umgebungsdatei, exportiert dann alle Umgebungsvariablen in dieser Datei und führt anschließend den Befehl aus.
VERWENDUNGSZWECK:
quelle
Ich bin auf diesen Thread gestoßen, als ich versucht habe, Docker
--env-file
in einer Shell wiederzuverwenden . Ihr Format ist nicht bash-kompatibel, aber es ist einfach:name=value
kein 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):
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
FOO
)quelle
Leerzeichen im Wert
Hier gibt es viele gute Antworten, aber ich fand, dass sie alle keine Unterstützung für Leerzeichen im Wert haben:
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 :
Und eine mit Lesezeile in einer Schleife basierend auf @ john1024 Antwort
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 :)quelle
sed
Lösung modifizieren , damit sie funktioniert. Aber zuerst eine Erklärung:-e
ist die Abkürzung für--expression
, die nur sagt,sed
welche Operationen durchzuführen sind.-e /^$/d
löscht die leeren Zeilen aus der Ausgabe (nicht die Datei).-e /^#/d
löscht die Bash-Kommentare (Zeilen, die mit # beginnen) aus der Ausgabe.'s/.*/declare -x "&"/g'
ersetzt (ersetzt) die verbleibenden Zeilen durchdeclare -x "ENV_VAR="VALUE""
. Wenn Sie dies, zumindest für mich, beschaffen, hat es nicht funktioniert. Stattdessen musste ich verwendensource <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x &/g' .env)
, um den zusätzlichen"
Wrapper zu entfernen .ENV_VAR="lorem ipsum"
, ich habeENV_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 anstattlorem ipsum
mit"lorem ipsum"
Wert zu enden - mit Anführungszeichen. Danke für die Erklärungen :)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 richtigensed
Optionen selbst zu finden!versuche so etwas
quelle
Wie es funktioniert
.env
Datei lesen . Alle Variablen werden in die aktuelle Umgebung exportiert.declare -x VAR="val"
dass jede der Variablen in die Umgebung exportiert würde.Eigenschaften
.env
kann Kommentare haben.env
kann leere Zeilen haben.env
erfordert keine spezielle Kopf- oder Fußzeile wie in den anderen Antworten (set -a
undset +a
).env
muss nichtexport
für jeden Wert habenquelle
Wenn Sie eine Fehlermeldung erhalten, weil eine Ihrer Variablen einen Wert enthält, der Leerzeichen enthält, können Sie versuchen, bashs
IFS
(Internal Field Separator) zurückzusetzen\n
, damit bash dascat .env
Ergebnis als Liste von Parametern für dieenv
ausführbare Datei interpretiert .Beispiel:
Siehe auch:
quelle
Meine .env-Datei sieht folgendermaßen aus:
Auf die @henke - Methode enthält der exportierte Wert die Anführungszeichen
"
Ich möchte jedoch, dass der exportierte Wert nur Folgendes enthält:
Um das Problem zu beheben, bearbeite ich den Befehl zum Löschen der Anführungszeichen:
quelle
Dieser behandelt Leerzeichen auf der rechten Seite und überspringt 'seltsame' Variablen wie Bash-Moduldefinitionen (mit '()' darin):
quelle