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 prac1
w wierszu poleceń, nie ustawia zmiennych środowiskowych
Próbowałem również użyć, source ./conf/$1
ale 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.
bash
variables
environment-variables
hugo19941994
źródło
źródło
Odpowiedzi:
Problem z twoim podejściem polega na tym,
export
żewhile
pę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
export
polecenie w samym pliku:Następnie musisz podać źródło w pliku w bieżącej powłoce, używając:
LUB
źródło
export
nie 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
.< <(commands that generate output)
set -o allexport
export
go zepsuje dla takich rzeczy jak Java, SystemD lub inne narzędziaawk '{print "export " $0}' envfile
polecenie wygody, aby dołączyć eksport na początek każdej liniiMoże to być pomocne:
Powodem, dla którego go używam jest to, że chcę testować
.env
rzeczy 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.
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 ):A jeśli chcesz
unset
wszystkie zmienne zdefiniowane w pliku, użyj tego:Aktualizacja:
Aby również obsługiwać wartości ze spacjami, użyj:
w systemach GNU - lub:
w systemach BSD.
źródło
export $(cat .env)
ale nie wiem, jak sobie poradzić ze spacjami.-d
do 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.env
ma spacje. Wiesz, dlaczego to nie działa?eval $(cat .env) rails
-o allexport
umożliwia eksport wszystkich następujących definicji zmiennych.+o allexport
wyłącza tę funkcję.źródło
.env
plik zawiera komentarze. Dzięki!set -o allexport; source conf-file; set +o allexport
set -a; . conf-file; set +a
.Jeśli
env.txt
jest jak: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 :
źródło
-a
jest równoważne zallexport
. Innymi słowy, każde przypisanie zmiennych w powłoce jestexport
edytowane 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.htmlallexport
Opcja jest mowa w kilku innych odpowiedzi tutaj, dla którychset -a
jest 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:źródło
VAR=
.źródło
eval $(cat .env | sed 's/^[^$]/export /')
pozwala mieć puste linie dla lepszej czytelności.cat .env | sed 's/^[^$]/export /'
odcina to początkowy znak. Tj. Po plik,A=foo\nB=bar\n
który dostajęexport =foo\nexport =bar\n
. To działa lepiej pomijanie pustych linii:cat .env | sed '/^$/! s/^/export /'
.cat
w obu przypadkach nie potrzebujesz :eval $(sed 's/^/export /' .env)
działa równie dobrze.)Znalazłem najbardziej efektywny sposób:
Wyjaśnienie
Kiedy mamy taki
.env
plik:bieg
xargs < .env
dostaniekey=val foo=bar
więc dostaniemy
export key=val foo=bar
i właśnie tego potrzebujemy!Ograniczenie
źródło
env
tworzą ten format.Oto inne
sed
rozwiązanie, które nie działa eval lub wymaga ruby:To dodaje eksport, zachowując komentarze do linii zaczynających się od komentarza.
.env zawartość
próbny przebieg
Uważam, że jest to szczególnie przydatne podczas konstruowania takiego pliku w celu załadowania go do pliku jednostki systemowej
EnvironmentFile
.źródło
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ć:Z dokumentacji zestawu wyodrębniono :
I to również:
źródło
Poprawa odpowiedzi Silasa Paula
eksportowanie zmiennych do podpowłoki czyni je lokalnymi dla komendy.
(export $(cat .env | xargs) && rails c)
źródło
(set -a; source dev.env; set +a; rails c)
aby uzyskać również korzyści z pozyskiwania (np. Skrypt może wykonać).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 allexport
ma tę zaletę, właściwie pomijając komentarze bez regex.set +o
samo z siebie wypisuje wszystkie bieżące opcje w formacie, który bash może później wykonać. Przydatne:set -o
samo w sobie wyświetla wszystkie bieżące opcje w formacie przyjaznym dla człowieka.źródło
exec env -i bash
wyczyściłem istniejące środowisko przed wywołaniem,eval
jeśli potrzebujesz cofnąć ustawienia zmiennych, które są ustawione tylko wewnątrz.env
.Najkrótszy sposób, jaki znalazłem:
Twój
.env
plik:Więc po prostu
Bonus: Ponieważ jest to krótki linijka, jest bardzo przydatny w
package.json
plikuźródło
VARIABLE_NAME="A_VALUE"
Prostsze:
export
do wszystkich liniieval
cała rzeczeval $(cat .env | sed -e /^$/d -e /^#/d -e 's/^/export /')
Kolejna opcja (nie musisz biegać
eval
(dzięki @Jaydeep)):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_profile
lub ... po prostu utwórz nową kartę / okno i problem zostanie rozwiązany) nazywasz to tak:source_envfile .env
źródło
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'
.Możesz użyć oryginalnego skryptu, aby ustawić zmienne, ale musisz wywołać go w następujący sposób (z samodzielną kropką):
Może również występować problem z
cat | while read
podejściem. Poleciłbym zastosować to podejściewhile read line; do .... done < $FILE
.Oto działający przykład:
źródło
test.conf
jako 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).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"
:źródło
Oto mój wariant:
w porównaniu z poprzednimi rozwiązaniami:
.env
nie są narażone na wywołujące)set
opcjiset -a
.
zamiastsource
unikać bashizmu.env
ładowanie się nie powiedzieźródło
set -a && . ./.env && "$@" && echo "your comand here"
Pracuję z komponentem dokującym i
.env
plikami na Macu i chciałem zaimportować go.env
do mojej powłoki bash (do testowania), a „najlepszą” odpowiedzią tutaj było potknięcie o następującą zmienną:.env
Rozwiązanie
Skończyło się więc na użyciu
eval
i zawijaniu env var defs w pojedyncze cudzysłowy.Wersja Bash
źródło
Mój .env:
Wywoływanie:
Odwołanie /unix/79068/how-to-export-variables-that-are-set-all-at-once
źródło
Mam problemy z wcześniej sugerowanymi rozwiązaniami:
$()
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):
źródło
Moje wymagania to:
export
prefiksów (dla zgodności z dotenv)Pełna działająca wersja skompilowana z powyższych odpowiedzi:
źródło
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
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
Ten skrypt pobierze pierwszy argument jako plik środowiskowy, a następnie wyeksportuje wszystkie zmienne środowiskowe w tym pliku, a następnie uruchomi komendę.
STOSOWANIE:
źródło
Natknąłem się na ten wątek, gdy próbowałem ponownie użyć Dockera
--env-file
w powłoce. Ich format nie jest zgodny z bash, ale jest prosty:name=value
bez 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):
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
FOO
)źródło
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:
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ź :
I jeden z linią odczytu w pętli opartej na odpowiedzi @ john1024
Kluczem tutaj jest używanie
declare -x
i 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 :)źródło
sed
rozwiązanie, aby działało. Ale najpierw jakieś wyjaśnienie:-e
jest skrótem--expression
, który po prostu mówi,sed
jakie operacje podjąć.-e /^$/d
usuwa puste linie z danych wyjściowych (nie pliku).-e /^#/d
usuwa komentarze wyjściowe (wiersze zaczynające się od #) z danych wyjściowych.'s/.*/declare -x "&"/g'
zamienia (zastępuje) pozostałe linie nadeclare -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.ENV_VAR="lorem ipsum"
, mamENV_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 zamiastlorem ipsum
skończyłem z"lorem ipsum"
wartością - z cytatami. Dziękuję za wyjaśnienia :)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ściwychsed
opcji!spróbuj czegoś takiego
źródło
Jak to działa
.env
plik. Wszystkie zmienne zostaną wyeksportowane do bieżącego środowiska.declare -x VAR="val"
wszystkie zmienne do środowiska.funkcje
.env
może mieć komentarze.env
może mieć puste linie.env
nie wymaga specjalnego nagłówka ani stopki, jak w innych odpowiedziach (set -a
iset +a
).env
nie wymaga posiadaniaexport
dla każdej wartościźródło
Jeśli pojawia się błąd, ponieważ jedna ze zmiennych zawiera wartość zawierającą białe spacje, możesz spróbować zresetować bash
IFS
(Internal Field Separator),\n
aby pozwolić interpretacji bash interpretowaćcat .env
wynik jako listę parametrówenv
pliku wykonywalnego.Przykład:
Zobacz też:
źródło
Mój plik .env wygląda następująco:
Korzystając ze sposobów @henke , wyeksportowana wartość zawiera znaki cudzysłowu
"
Ale chcę, aby eksportowana wartość zawierała tylko:
Aby to naprawić, edytuję polecenie, aby usunąć znaki cudzysłowu:
źródło
Ten radzi sobie ze spacjami na RHS i pomija „dziwne” zmienne, takie jak definicje modułów bash (z zawartym w nich „()”):
źródło