it-swarm.com.de

Setze Umgebungsvariablen aus der Datei der Schlüssel / Wert-Paare

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 eines 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 dann die Datei mit folgendem 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 zu verwenden, aber das gleiche Problem tritt immer noch auf

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

389
hugo19941994

Problem bei Ihrer Vorgehensweise ist, dass die export in der while -Schleife in einer Sub-Shell stattfindet und diese Variable in der aktuellen Shell (übergeordnete Shell der while-Schleife) nicht verfügbar ist.

Fügen Sie den Befehl export in die Datei selbst ein:

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 folgendem Befehl importieren:

. ./conf/prac1

OR

source ./conf/prac1
151
anubhava

Dies könnte hilfreich sein:

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

Ich benutze dies, um .env in meiner Rails Konsole zu testen.

gabrielf hat eine gute Möglichkeit gefunden, die Variablen lokal zu halten. Dies löst das potenzielle Problem, wenn von Projekt zu Projekt gewechselt wird.

env $(cat .env | xargs) Rails

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


Update:

Verwenden Sie dies, um Zeilen zu ignorieren, die mit # beginnen (danke an Petes Kommentar ):

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

Und wenn Sie alle in der Datei definierten Variablen unset möchten, verwenden Sie Folgendes:

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

Update:

Um auch Werte mit Leerzeichen zu behandeln, verwenden Sie:

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

auf GNU Systemen - oder:

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

auf BSD-Systemen.

691
Silas Paul

-o allexport ermöglicht den Export aller folgenden Variablendefinitionen. +o allexport deaktiviert diese Funktion.

set -o allexport
source conf-file
set +o allexport
311
user4040650
set -a
. ./env.txt
set +a

Wenn env.txt wie folgt lautet:

VAR1=1
VAR2=2
VAR3=3
...
91
Dan Kowalczyk

Die Option allexport wird hier in einigen anderen Antworten erwähnt, für die set -a die Abkürzung ist. 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, möglich sind. Mein .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 [email protected]
  dotenv
}
27
gsf
eval $(cat .env | sed 's/^/export /')
23
selvan

Hier ist eine andere sed Lösung, die nicht eval läuft oder Ruby benötigt:

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

Dies fügt einen Export hinzu, wobei Kommentare zu Zeilen, die mit einem Kommentar beginnen, beibehalten werden.

.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 unit-Datei mit EnvironmentFile erstellte.

20
tutuDajuju

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

Wenn das Skript wie folgt 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 Dokumentation festlegen 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 verwendet werden kann. Schreibgeschützte Variablen können nicht zurückgesetzt werden. Im POSIX-Modus werden nur Shell-Variablen aufgelistet.

Wenn Optionen angegeben werden, setzen sie Shell-Attribute oder heben sie auf. Optionen haben, falls angegeben, folgende Bedeutung:

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

Und das auch:

Durch die Verwendung von "+" anstelle von "-" werden diese Optionen deaktiviert. Die Optionen können auch beim Aufruf der Shell verwendet werden. Die aktuellen Optionen finden Sie in $ -.

14
Nagev

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

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

Die Verwendung von set -o allexport hat den Vorteil, dass Kommentare ohne Regex korrekt übersprungen werden.

set +o gibt alle Ihre aktuellen Optionen in einem Format aus, das bash später ausführen kann. Ebenfalls praktisch: set -o gibt alle aktuellen Optionen in einem benutzerfreundlichen Format aus.

12
jwfearn

Die Antwort von Silas Paul verbessern

durch das Exportieren der Variablen in einer Subshell werden sie für den Befehl lokal.

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

11
Jaydeep

Einfacher:

  1. nimm den Inhalt der Datei
  2. entferne alle leeren Zeilen (nur falls du ein paar Sachen getrennt hast)
  3. kommentare entfernen (nur für den Fall, dass Sie einige hinzugefügt haben ...)
  4. fügen Sie export zu allen Zeilen hinzu
  5. eval die ganze Sache

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

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

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

Wenn Sie Ihr Leben wirklich einfach machen möchten, fügen Sie dies zu Ihrem ~/.bash_profile hinzu:

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 wie folgt: source_envfile .env

9
Javier Buzzi

Der kürzeste Weg, den ich gefunden habe:

Deine .env Datei:

VARIABLE_NAME="A_VALUE"

Dann einfach

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

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

  "scripts": {
    "echo:variable": ". ./.env && echo ${VARIABLE_NAME}"
  }
7
Flavien Volken

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
5
Victor Roetman

Sie können Ihr ursprüngliches Skript zum Festlegen der Variablen verwenden, müssen es jedoch wie folgt aufrufen (mit eigenständigem Punkt):

. ./minientrega.sh

Möglicherweise liegt auch ein Problem mit dem cat | while read -Ansatz vor. Ich würde empfehlen, den Ansatz while read line; do .... done < $FILE zu verwenden.

Hier ist ein funktionierendes Beispiel:

> 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
Extrapolator

Erstellen Sie zunächst eine Umgebungsdatei, die alle Schlüssel-Wert-Paare der folgenden Umgebungen enthält, und benennen Sie sie wie gewünscht in meinem Fall mit 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 folgt 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 nimmt das erste Argument als Umgebungsdatei, exportiert dann alle Umgebungsvariablen in dieser Datei und führt anschließend den Befehl aus.

SAGE:

./export_env.sh env_var.env python app.py
2
anand tripathi

Meine Anforderungen waren:

  • einfache .env Datei ohne export Präfixe (zur Kompatibilität mit dotenv)
  • stützwerte in Anführungszeichen: TEXT = "alpha bravo charlie"
  • unterstützende Kommentare, denen # und Leerzeilen vorangestellt sind
  • universell für Mac/BSD und Linux/GNU

Voll funktionsfähige Version, zusammengestellt aus den obigen Antworten:

  set -o allexport
  eval $(grep -v '^#' .env | sed 's/^/export /')
  set +o allexport
1
Alex

Ich arbeite mit Docker-Compose- und .env -Dateien auf dem Mac und wollte den .env (zum Testen) in meine Bash-Shell importieren.

. env

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

Lösung

Also habe ich eval verwendet und meine env var defs 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.
1
Nick Grealy

Leerzeichen im Wert

Hier gibt es viele gute Antworten, aber ich habe festgestellt, 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 Leerzeilen 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 ist, declare -x zu verwenden und die Zeile in doppelte Anführungszeichen zu setzen. Ich weiß nicht warum, aber wenn Sie den Loop-Code in mehrere Zeilen umformatieren, funktioniert er nicht - ich bin kein Bash-Programmierer, ich habe nur diese verschlungen, es ist immer noch magisch für mich :)

1

Ich habe Probleme mit den zuvor vorgeschlagenen Lösungen:

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

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

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

Wenn Sie eine Fehlermeldung erhalten, weil eine Ihrer Variablen einen Wert enthält, der Leerzeichen enthält, können Sie versuchen, bashs IFS (Internes Feldtrennzeichen) auf \n zurückzusetzen, damit bash cat .env interpretiert. Ergebnis als Liste von Parametern für die ausführbare Datei env.

Beispiel:

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

Siehe auch:

Ich bin auf diesen Thread gestoßen, als ich versuchte, Docker --env-files 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 posix-kompatibel machen, aber hier ist eines, das 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 behandelt in dem oben verlinkten Beispiel nicht drei Fälle :

  • bash: export: `123qwe=bar': not a valid identifier
  • bash: export: `org.spring.config=something': not a valid identifier
  • und es wird die Passthrough-Syntax nicht verarbeiten (eine bloße FOO)
0
Bob Zoller

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 von:

source .env; echo $USER; echo $PASS

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

0
Tudor Ilisoi