Ustaw zmienne środowiskowe z pliku par klucz / wartość

511

TL; DR: Jak wyeksportować zestaw par klucz / wartość z pliku tekstowego do środowiska powłoki?


Dla przypomnienia poniżej znajduje się oryginalna wersja pytania wraz z przykładami.

Piszę skrypt w bash, który analizuje pliki z 3 zmiennymi w określonym folderze, jest to jeden z nich:

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

Ten plik jest przechowywany w ./conf/prac1

Mój skrypt minientrega.sh następnie analizuje plik przy użyciu tego kodu:

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

Ale kiedy wykonuję minientrega.sh prac1w wierszu poleceń, nie ustawia zmiennych środowiskowych

Próbowałem również użyć, source ./conf/$1ale ten sam problem nadal występuje

Może jest na to inny sposób, po prostu muszę użyć zmiennych środowiskowych pliku, który przekazuję jako argument mojego skryptu.

hugo19941994
źródło
To samo na unix: unix.stackexchange.com/questions/31797/…
Ciro Santilli 19 冠状 病 六四 事件 法轮功
To samo z Ruby: stackoverflow.com/questions/2139080/... , klejnot, który to robi: github.com/bkeepers/dotenv
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
To świetne pytanie, ale jest sformułowane zbyt konkretnie, z konkretnymi nazwami zmiennych („MINIENTREGA_FECHALIMITE”? Co to znaczy?) I liczbami (3). Ogólne pytanie brzmi: „Jak wyeksportować zestaw par klucz / wartość z pliku tekstowego do środowiska powłoki”.
Dan Dascalescu
Odpowiedź na to pytanie jest już dostępna na unix.SE i jest prawdopodobnie bardziej na ten temat.
Dan Dascalescu,

Odpowiedzi:

208

Problem z twoim podejściem polega na tym, exportże whilepętla dzieje się w podpowłoce, a te zmienne nie będą dostępne w bieżącej powłoce (powłoka nadrzędna pętli while).

Dodaj exportpolecenie w samym pliku:

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

Następnie musisz podać źródło w pliku w bieżącej powłoce, używając:

. ./conf/prac1

LUB

source ./conf/prac1
anubhava
źródło
4
Chociaż czytając wiersz po linijce pliku i przejściu do każdej linii exportnie jest idealny, problem może być również ustalona po prostu za pomocą przekierowania wejścia na pętli: while read line; do ... ; done < ./conf/$1.
chepner
4
A jeśli nie pochodzi z pliku, użyj< <(commands that generate output)
o11c
5
Masz bardziej czyste rozwiązanie , wolęset -o allexport
heralight
2
Jeśli używasz tego pliku .env między systemami, wstawianie exportgo zepsuje dla takich rzeczy jak Java, SystemD lub inne narzędzia
FilBot3
1
awk '{print "export " $0}' envfilepolecenie wygody, aby dołączyć eksport na początek każdej linii
Shardj
887

Może to być pomocne:

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

Powodem, dla którego go używam jest to, że chcę testować .envrzeczy w mojej konsoli szynowej.

gabrielf wymyślił dobry sposób na utrzymanie zmiennych lokalnych. To rozwiązuje potencjalny problem podczas przechodzenia od projektu do projektu.

env $(cat .env | xargs) rails

Przetestowałem to z bash 3.2.51(1)-release


Aktualizacja:

Aby zignorować linie zaczynające się od #, użyj tego (dzięki komentarzowi Pete'a ):

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

A jeśli chcesz unsetwszystkie zmienne zdefiniowane w pliku, użyj tego:

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

Aktualizacja:

Aby również obsługiwać wartości ze spacjami, użyj:

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

w systemach GNU - lub:

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

w systemach BSD.

Silas Paul
źródło
6
Dzięki, podoba mi się, że nie wymaga to dodawania niczego do pliku - pozwala na zgodność z formatem Foreman (Procfile) .env.
natevw
29
Wymyśliłem rozwiązanie: szyny env $ (cat .env | xargs)
gabrielf
4
Wydaje się, że to nie działa, jeśli którakolwiek z wartości env ma spacje, chociaż tak naprawdę nie jestem pewien, jaki jest najlepszy / pożądany sposób określania wartości za pomocą spacji. github.com/ddollar/foreman/issues/56 mówi, że powinno tak działać, export $(cat .env)ale nie wiem, jak sobie poradzić ze spacjami.
Dan Benamy
6
@BenjaminWheeler GNU linux ma -ddo ustawiania separatora, więc próbuję env $(cat .env | xargs -d '\n') rails, ale nadal występuje błąd z plikiem nie znaleziono, jeśli .envma spacje. Wiesz, dlaczego to nie działa?
Bailey Parker,
19
Oto krótsza odmianaeval $(cat .env) rails
manalang 26.04.16
412

-o allexportumożliwia eksport wszystkich następujących definicji zmiennych. +o allexportwyłącza tę funkcję.

set -o allexport
source conf-file
set +o allexport
użytkownik4040650
źródło
9
Działa jak marzenie! Nawet jeśli .envplik zawiera komentarze. Dzięki!
Slava Fomin II
9
I w jednej liniiset -o allexport; source conf-file; set +o allexport
HarlemSquirrel,
1
Jest to świetny sposób na odczytanie pliku właściwości, gdy wtyczka Jenkins EnvInject nie działa. Dzięki!
Teresa Peters
21
@CMCDragonkai, dla POSIX byłoby set -a; . conf-file; set +a.
Charles Duffy
3
Ta metoda działa, jeśli zmienne środowiskowe mają spacje. Wiele innych nie. Podczas gdy robi to metoda eval (), również trochę dziwię się przy użyciu eval
CommandZ
137
set -a
. ./env.txt
set +a

Jeśli env.txtjest jak:

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

Objaśnienia -a jest równoważne z allexport . Innymi słowy, każde przypisanie zmiennych w powłoce jest eksportowane do środowiska (do wykorzystania przez wiele procesów potomnych). Więcej informacji można znaleźć w dokumentacji wbudowanej zestawu :

-a     Każda zmienna lub funkcja, która jest tworzona lub modyfikowana, otrzymuje atrybut eksportu i jest oznaczana do eksportu do środowiska kolejnych poleceń.

Użycie „+” zamiast „-” powoduje wyłączenie tych opcji. Opcji można również użyć po wywołaniu powłoki. Aktualny zestaw opcji można znaleźć w $ -.

Dan Kowalczyk
źródło
Czy potrafisz wyjaśnić -a i + a?
Otto
11
@Otto -ajest równoważne z allexport. Innymi słowy, każde przypisanie zmiennych w powłoce jest exportedytowane w środowisku (do użycia przez wiele procesów potomnych). Zobacz także ten artykuł gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
Dan Kowalczyk
33

allexportOpcja jest mowa w kilku innych odpowiedzi tutaj, dla których set -ajest skrót. Pozyskiwanie .env jest naprawdę lepsze niż zapętlanie linii i eksportowanie, ponieważ pozwala na komentarze, puste linie, a nawet zmienne środowiskowe generowane przez polecenia. Mój .bashrc obejmuje:

# .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
źródło
3
To ładnie wygląda, ale czy rozładowujesz zmienne środowiskowe, gdy opuszczasz katalog?
Bastian Venthur
1
Nie rozbieram zmiennych i to nigdy nie było problemem. Moje aplikacje zwykle używają nazw zmiennych, które są odrębne, a jeśli się nakładają, ustawię je na puste w .env z VAR=.
gsf
26
eval $(cat .env | sed 's/^/export /')
selvan
źródło
1
Korzystanie eval $(cat .env | sed 's/^[^$]/export /')pozwala mieć puste linie dla lepszej czytelności.
Mario Uher,
2
Uważam, że cat .env | sed 's/^[^$]/export /'odcina to początkowy znak. Tj. Po plik, A=foo\nB=bar\nktóry dostaję export =foo\nexport =bar\n. To działa lepiej pomijanie pustych linii: cat .env | sed '/^$/! s/^/export /'.
Owen S.
(Zwracam również uwagę na golfistów z kodem UNIX, że catw obu przypadkach nie potrzebujesz : eval $(sed 's/^/export /' .env)działa równie dobrze.)
Owen S.
21

Znalazłem najbardziej efektywny sposób:

export $(xargs < .env)

Wyjaśnienie

Kiedy mamy taki .envplik:

key=val
foo=bar

bieg xargs < .envdostaniekey=val foo=bar

więc dostaniemy export key=val foo=bari właśnie tego potrzebujemy!

Ograniczenie

  1. Nie obsługuje przypadków, w których wartości zawierają spacje. Polecenia takie jak env tworzą ten format. - @Shardj
Huan
źródło
3
Nie obsługuje przypadków, w których wartości zawierają spacje. Polecenia takie jak envtworzą ten format.
Shardj
19

Oto inne sedrozwiązanie, które nie działa eval lub wymaga ruby:

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

To dodaje eksport, zachowując komentarze do linii zaczynających się od komentarza.

.env zawartość

A=1
#B=2

próbny przebieg

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

Uważam, że jest to szczególnie przydatne podczas konstruowania takiego pliku w celu załadowania go do pliku jednostki systemowejEnvironmentFile .

tutuDajuju
źródło
nie obsługuje wielu linii w OSX
Abdennour TOUMI
17

Poprosiłem o odpowiedź użytkownika 4040650, ponieważ jest on zarówno prosty, jak i pozwala na komentarze w pliku (tj. Wiersze zaczynające się od #), co jest dla mnie bardzo pożądane, ponieważ można dodawać komentarze wyjaśniające zmienne. Po prostu przepisuję w kontekście pierwotnego pytania.

Jeśli skrypt jest wywoływany, jak wskazano minientrega.sh prac1:, wtedy minientrega.sh może mieć:

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

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

Z dokumentacji zestawu wyodrębniono :

To wbudowane jest tak skomplikowane, że zasługuje na własną sekcję. set pozwala zmieniać wartości opcji powłoki i ustawiać parametry pozycyjne lub wyświetlać nazwy i wartości zmiennych powłoki.

ustaw [--abefhkmnptuvxBCEHPT] [-o nazwa-opcji] [argument…] ustaw [+ abefhkmnptuvxBCEHPT] [+ o nazwa-opcji] [argument…]

Jeśli nie podano żadnych opcji ani argumentów, set wyświetla nazwy i wartości wszystkich zmiennych powłoki i funkcji, posortowane według bieżących ustawień regionalnych, w formacie, który może być ponownie użyty jako dane wejściowe do ustawienia lub zresetowania aktualnie ustawionych zmiennych. Zmiennych tylko do odczytu nie można zresetować. W trybie POSIX są wyświetlane tylko zmienne powłoki.

Gdy podano opcje, ustawiają lub usuwają atrybuty powłoki. Opcje, jeśli są określone, mają następujące znaczenie:

-a Każda zmienna lub funkcja, która jest tworzona lub modyfikowana, otrzymuje atrybut eksportu i jest oznaczana do eksportu do środowiska kolejnych poleceń.

I to również:

Użycie „+” zamiast „-” powoduje wyłączenie tych opcji. Opcji można również użyć po wywołaniu powłoki. Aktualny zestaw opcji można znaleźć w $ -.

Nagev
źródło
14

Poprawa odpowiedzi Silasa Paula

eksportowanie zmiennych do podpowłoki czyni je lokalnymi dla komendy.

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

Jaydeep Solanki
źródło
Następnie możesz użyć tego, (set -a; source dev.env; set +a; rails c)aby uzyskać również korzyści z pozyskiwania (np. Skrypt może wykonać).
wacha
12

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

Spowoduje to zapisanie / przywrócenie oryginalnych opcji, bez względu na to, jakie mogą być.

Używanie set -o allexportma tę zaletę, właściwie pomijając komentarze bez regex.

set +osamo z siebie wypisuje wszystkie bieżące opcje w formacie, który bash może później wykonać. Przydatne: set -osamo w sobie wyświetla wszystkie bieżące opcje w formacie przyjaznym dla człowieka.

jwfearn
źródło
2
Prawdopodobnie exec env -i bashwyczyściłem istniejące środowisko przed wywołaniem, evaljeśli potrzebujesz cofnąć ustawienia zmiennych, które są ustawione tylko wewnątrz .env.
b4hand
11

Najkrótszy sposób, jaki znalazłem:

Twój .envplik:

VARIABLE_NAME="A_VALUE"

Więc po prostu

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

Bonus: Ponieważ jest to krótki linijka, jest bardzo przydatny w package.jsonpliku

  "scripts": {
    "echo:variable": ". ./.env && echo ${VARIABLE_NAME}"
  }
Flavien Volken
źródło
A jeśli masz dużo zmiennych?
Madeo,
@Madeo możesz dodać tyle linii, ile chcesz, w taki sam sposób, jak liniaVARIABLE_NAME="A_VALUE"
Flavien Volken
9

Prostsze:

  1. pobierz zawartość pliku
  2. usuń puste wiersze (po prostu wstaw kilka rzeczy)
  3. usuń wszelkie komentarze (po prostu dodaj kilka ...)
  4. dodaj exportdo wszystkich linii
  5. eval cała rzecz

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

Kolejna opcja (nie musisz biegać eval(dzięki @Jaydeep)):

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

Wreszcie, jeśli chcesz, aby Twoje życie było NAPRAWDĘ łatwe, dodaj to do ~/.bash_profile:

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

(UPEWNIJ SIĘ, ŻE ZMIENIŁEŚ SWOJE PODSTAWOWE USTAWIENIA !!! source ~/.bash_profilelub ... po prostu utwórz nową kartę / okno i problem zostanie rozwiązany) nazywasz to tak:source_envfile .env

Javier Buzzi
źródło
2
Musiałem przeczytać .env tekst z gitlab zmiennej tajnym dla rurociągu: W oparciu o rozwiązania tego polecenia pracował dla mnie source <( echo $(sed -E -n 's/[^#]+/ &/ p' <(echo "${2}" | tr -d '\r')) );. W jakiś sposób gitlab zapisuje tajną zmienną ze znakiem powrotu karetki systemu Windows, więc musiałem to przyciąć tr -d '\r'.
metanerd
6

Możesz użyć oryginalnego skryptu, aby ustawić zmienne, ale musisz wywołać go w następujący sposób (z samodzielną kropką):

. ./minientrega.sh

Może również występować problem z cat | while readpodejściem. Poleciłbym zastosować to podejście while read line; do .... done < $FILE.

Oto działający przykład:

> 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
Ekstrapolator
źródło
W przeciwieństwie do większości innych odpowiedzi, to rozwiązanie nie sprawdza się test.confjako plik skryptu. To czyni to lepszym. Bezpieczniej jest nie zezwalać na wykonywanie skryptów, chyba że faktycznie jest to potrzebne, zwłaszcza jeśli ktoś nie zdaje sobie sprawy, że tak się dzieje (lub zapomina).
Meustrus
5

Opierając się na innych odpowiedziach, oto sposób na wyeksportowanie tylko podzestawu wierszy w pliku, w tym wartości ze spacjami, takimi jak PREFIX_ONE="a word":

set -a
. <(grep '^[ ]*PREFIX_' conf-file)
set +a
Victor Roetman
źródło
5

Oto mój wariant:

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

w porównaniu z poprzednimi rozwiązaniami:

  • nie przecieka zmiennych poza zakresem (wartości z .envnie są narażone na wywołujące)
  • nie blokuje setopcji
  • zwraca kod wyjścia wykonanej komendy
  • używa kompatybilnego z posix set -a
  • używa .zamiast sourceunikać bashizmu
  • polecenie nie jest wywoływane, jeśli .envładowanie się nie powiedzie
with_env rails console
Elan Ruusamäe
źródło
Możesz także uruchomić inline (zmienne są narażone na bieżącą sesję terminalową): set -a && . ./.env && "$@" && echo "your comand here"
Giovanne Afonso
4

Pracuję z komponentem dokującym i .envplikami na Macu i chciałem zaimportować go .envdo mojej powłoki bash (do testowania), a „najlepszą” odpowiedzią tutaj było potknięcie o następującą zmienną:

.env

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

Rozwiązanie

Skończyło się więc na użyciu evali zawijaniu env var defs w pojedyncze cudzysłowy.

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

Wersja Bash

$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.
Nick Grealy
źródło
3

Mój .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

Wywoływanie:

source .env; echo $USER; echo $PASS

Odwołanie /unix/79068/how-to-export-variables-that-are-set-all-at-once

Tudor Ilisoi
źródło
2

Mam problemy z wcześniej sugerowanymi rozwiązaniami:

  • Rozwiązanie @ anubhava sprawia, że ​​pisanie plików konfiguracyjnych przyjaznych bashowi jest bardzo irytujące bardzo szybko, a także - nie zawsze możesz chcieć eksportować swoją konfigurację.
  • Rozwiązanie @Silas Paul psuje się, gdy masz zmienne ze spacjami lub innymi znakami, które działają dobrze w wartościach cytowanych, ale $()robią bałagan.

Oto moje rozwiązanie, które wciąż jest dość okropne IMO - i nie rozwiązuje problemu „eksportuj tylko do jednego dziecka” rozwiązanego przez Silasa (chociaż prawdopodobnie można go uruchomić w podpowłoce, aby ograniczyć zakres):

source .conf-file
export $(cut -d= -f1 < .conf-file)
Guss
źródło
2

Moje wymagania to:

  • prosty plik .env bez exportprefiksów (dla zgodności z dotenv)
  • obsługa wartości w cudzysłowach: TEXT = "alpha bravo charlie"
  • obsługa komentarzy z prefiksem # i pustymi wierszami
  • uniwersalny zarówno dla mac / BSD, jak i linux / GNU

Pełna działająca wersja skompilowana z powyższych odpowiedzi:

  set -o allexport
  eval $(grep -v '^#' .env | sed 's/^/export /')
  set +o allexport
Alex
źródło
1
jaki jest sens „-o allexport”, jeśli i tak dodasz je do „eksportu”?
il - ya
2

Najpierw utwórz plik środowiska, który będzie zawierał wszystkie pary klucz-wartość środowisk takich jak poniżej i nazwij go, jak chcesz, w moim przypadku env_var.env

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

Następnie utwórz skrypt, który wyeksportuje wszystkie zmienne środowiskowe dla środowiska python, takie jak poniżej, i nazwij go tak export_env.sh

#!/usr/bin/env bash

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

set -o allexport
source $ENV_FILE
set +o allexport

$CMD

Ten skrypt pobierze pierwszy argument jako plik środowiskowy, a następnie wyeksportuje wszystkie zmienne środowiskowe w tym pliku, a następnie uruchomi komendę.

STOSOWANIE:

./export_env.sh env_var.env python app.py
anand tripathi
źródło
1

Natknąłem się na ten wątek, gdy próbowałem ponownie użyć Dockera --env-filew powłoce. Ich format nie jest zgodny z bash, ale jest prosty: name=valuebez cytowania, bez podstawiania. Ignorują również puste wiersze i #komentarze.

Nie mogłem do końca zapewnić zgodności z posixem, ale oto jedna, która powinna działać w powłokach typu bash (testowana w Zsh na OSX 10.12.5 i bash na Ubuntu 14.04):

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

Nie będzie obsługiwał trzech przypadków w przykładzie z dokumentów powiązanych powyżej:

  • bash: export: `123qwe=bar': not a valid identifier
  • bash: export: `org.spring.config=something': not a valid identifier
  • i nie obsłuży składni przejścia (goły FOO)
Bob Zoller
źródło
1

Białe spacje w wartości

Jest tu wiele świetnych odpowiedzi, ale nie znalazłem w nich wsparcia dla białych znaków w wartości:

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

Znalazłem 2 rozwiązania, które działają z takimi wartościami z obsługą pustych wierszy i komentarzy.

Jeden na podstawie sed i @ Javier-Buzzi odpowiedź :

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

I jeden z linią odczytu w pętli opartej na odpowiedzi @ john1024

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

Kluczem tutaj jest używanie declare -xi wstawianie wiersza w podwójnych cudzysłowach. Nie wiem dlaczego, ale kiedy sformatujesz kod pętli do wielu linii, to nie zadziała - nie jestem programistą bash, po prostu je pochłonąłem, to wciąż dla mnie magia :)

Janusz Skonieczny
źródło
1
Musiałem zmodyfikować sedrozwiązanie, aby działało. Ale najpierw jakieś wyjaśnienie: -ejest skrótem --expression, który po prostu mówi, sedjakie operacje podjąć. -e /^$/dusuwa puste linie z danych wyjściowych (nie pliku). -e /^#/dusuwa komentarze wyjściowe (wiersze zaczynające się od #) z danych wyjściowych. 's/.*/declare -x "&"/g'zamienia (zastępuje) pozostałe linie na declare -x "ENV_VAR="VALUE"". Kiedy to źródło, przynajmniej dla mnie, nie działało. Zamiast tego musiałem użyć source <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x &/g' .env), aby usunąć dodatkowe "opakowanie.
jcasner
Nie używam ENV_VAR="lorem ipsum", mam ENV_VAR=lorem ipsum, bez cudzysłowów w pliku .env. Teraz nie jestem pewien, dlaczego, ale prawdopodobnie było to problematyczne w przypadku innych narzędzi, które analizują ten plik. I zamiast lorem ipsumskończyłem z "lorem ipsum"wartością - z cytatami. Dziękuję za wyjaśnienia :)
Janusz Skonieczny
1
Gdyby to był mój wybór, nie użyłbym ENV_VAR="lorem ipsum"żadnego z nich. W moim przypadku mój dostawca hostingu generuje ten plik na podstawie niektórych opcji konfiguracji, które ustawiłem, i wstawiają podwójne cudzysłowy. Więc jestem zmuszony do obejścia tego. Dzięki za pomoc tutaj - zaoszczędziłem dużo czasu na samodzielne wypracowanie właściwych sedopcji!
jcasner
1

spróbuj czegoś takiego

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

Jak to działa

  1. Utwórz plik tymczasowy.
  2. Zapisz wszystkie bieżące wartości zmiennych środowiskowych do pliku tymczasowego.
  3. Włącz eksportowanie wszystkich deklarowanych zmiennych w skrypcie źródłowym do środowiska.
  4. Czytać .env plik. Wszystkie zmienne zostaną wyeksportowane do bieżącego środowiska.
  5. Wyłącz eksportowanie wszystkich deklarowanych zmiennych w skrypcie źródłowym do środowiska.
  6. Przeczytaj zawartość pliku tymczasowego. Każda linia miałabydeclare -x VAR="val" wszystkie zmienne do środowiska.
  7. Usuń plik tymczasowy.
  8. Odznacz zmienną przechowującą nazwę pliku temp.

funkcje

  • Zachowuje wartości zmiennych już ustawionych w środowisku
  • .env może mieć komentarze
  • .env może mieć puste linie
  • .envnie wymaga specjalnego nagłówka ani stopki, jak w innych odpowiedziach ( set -aiset +a )
  • .envnie wymaga posiadania exportdla każdej wartości
  • jednowarstwowy
Alex Skrypnyk
źródło
0

Mój plik .env wygląda następująco:

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

Korzystając ze sposobów @henke , wyeksportowana wartość zawiera znaki cudzysłowu"

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

Ale chcę, aby eksportowana wartość zawierała tylko:

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

Aby to naprawić, edytuję polecenie, aby usunąć znaki cudzysłowu:

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

Ten radzi sobie ze spacjami na RHS i pomija „dziwne” zmienne, takie jak definicje modułów bash (z zawartym w nich „()”):

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
źródło