Tetapkan variabel lingkungan dari file pasangan kunci / nilai

514

TL; DR: Bagaimana cara mengekspor satu set pasangan kunci / nilai dari file teks ke lingkungan shell?


Sebagai catatan, di bawah ini adalah versi asli dari pertanyaan, dengan contoh-contoh.

Saya sedang menulis skrip di bash yang mem-parsing file dengan 3 variabel dalam folder tertentu, ini adalah salah satunya:

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

File ini disimpan di ./conf/prac1

Script saya minientrega.sh kemudian mem-parsing file menggunakan kode ini:

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

Tetapi ketika saya mengeksekusi minientrega.sh prac1di baris perintah itu tidak mengatur variabel lingkungan

Saya juga mencoba menggunakan source ./conf/$1tetapi masalah yang sama masih berlaku

Mungkin ada beberapa cara lain untuk melakukan ini, saya hanya perlu menggunakan variabel lingkungan dari file yang saya berikan sebagai argumen dari skrip saya.

hugo19941994
sumber
Sama dengan unix: unix.stackexchange.com/questions/31797/…
Ciro Santilli 郝海东 冠状 病 六四 事件 事件
Sama dengan Ruby: stackoverflow.com/questions/2139080/… , permata yang melakukannya: github.com/bkeepers/dotenv
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Ini adalah pertanyaan yang bagus tapi terlalu spesifik, dengan nama variabel tertentu ("MINIENTREGA_FECHALIMITE"? Apa artinya itu?) Dan angka (3). Pertanyaan umumnya adalah, "Bagaimana cara saya mengekspor pasangan kunci / nilai dari file teks ke lingkungan shell".
Dan Dascalescu
Juga, ini sudah dijawab di unix.SE dan bisa dibilang lebih pada topik di sana.
Dan Dascalescu

Jawaban:

209

Masalah dengan pendekatan Anda adalah exportdi whileloop sedang terjadi di sub shell, dan variabel tersebut tidak akan tersedia di shell saat ini (shell induk dari while loop).

Tambahkan exportperintah dalam file itu sendiri:

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

Maka Anda perlu sumber dalam file di shell saat ini menggunakan:

. ./conf/prac1

ATAU

source ./conf/prac1
anubhava
sumber
4
Meskipun membaca file baris demi baris dan melewati setiap baris untuk exporttidak ideal, masalah ini juga bisa diperbaiki dengan hanya menggunakan input redirection pada loop: while read line; do ... ; done < ./conf/$1.
chepner
4
Dan jika itu bukan dari file, gunakan< <(commands that generate output)
o11c
5
Anda memiliki solusi yang lebih bersih , saya punya preferensi untukset -o allexport
heralight
2
Jika menggunakan file .env ini di antara sistem, memasukkan exportakan merusaknya untuk hal-hal seperti Java, SystemD, atau alat lain
FilBot3
1
awk '{print "export " $0}' envfileperintah kenyamanan untuk menambahkan ekspor ke awal setiap baris
Shardj
888

Ini mungkin membantu:

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

Alasan mengapa saya menggunakan ini adalah jika saya ingin menguji .envbarang-barang di konsol rel saya.

gabrielf datang dengan cara yang baik untuk menjaga variabel tetap lokal. Ini memecahkan masalah potensial ketika berpindah dari satu proyek ke proyek lainnya.

env $(cat .env | xargs) rails

Saya sudah menguji ini dengan bash 3.2.51(1)-release


Memperbarui:

Untuk mengabaikan garis yang dimulai dengan #, gunakan ini (terima kasih atas komentar Pete ):

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

Dan jika Anda ingin unsetsemua variabel yang ditentukan dalam file, gunakan ini:

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

Memperbarui:

Untuk juga menangani nilai dengan spasi, gunakan:

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

pada sistem GNU - atau:

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

pada sistem BSD.

Silas Paul
sumber
6
Terima kasih, saya suka ini tidak perlu menambahkan apa pun ke file - memungkinkan untuk kompatibilitas dengan format Foreman (Procfile) .env.
natevw
29
Saya datang dengan solusinya: env $ (cat .env | xargs) rails
gabrielf
4
Ini tampaknya tidak berfungsi jika salah satu nilai env memiliki spasi, meskipun saya sebenarnya tidak yakin apa cara terbaik / yang diinginkan untuk menentukan nilai dengan spasi. github.com/ddollar/foreman/issues/56 mengatakan itu seharusnya berfungsi, export $(cat .env)tetapi saya tidak tahu bagaimana membuat ruang itu.
Dan Benamy
6
@BenjaminWheeler GNU linux memiliki -dpengaturan pembatas, jadi saya mencoba env $(cat .env | xargs -d '\n') rails, tetapi masih ada kesalahan dengan file yang tidak ditemukan jika .envmemiliki spasi. Adakah yang tahu mengapa ini tidak berhasil?
Bailey Parker
19
Berikut variasi yang lebih pendekeval $(cat .env) rails
manalang
413

-o allexportmemungkinkan semua definisi variabel berikut untuk diekspor. +o allexportmenonaktifkan fitur ini.

set -o allexport
source conf-file
set +o allexport
pengguna4040650
sumber
9
Bekerja seperti pesona! Bahkan jika .envfile memiliki komentar di dalamnya. Terima kasih!
Slava Fomin II
9
Dan dalam satu barisset -o allexport; source conf-file; set +o allexport
HarlemSquirrel
1
Ini adalah cara terbaik untuk membaca dalam file properti, ketika plug-in Jenkins EnvInject tidak berfungsi. Terima kasih!
Teresa Peters
21
@ CMCDragonkai, untuk POSIX, itu akan menjadi set -a; . conf-file; set +a.
Charles Duffy
3
Metode ini berfungsi jika variabel lingkungan memiliki spasi di dalamnya. Banyak yang tidak. Sementara metode eval () tidak, saya juga sedikit merasa aneh dengan menggunakan eval
CommandZ
139
set -a
. ./env.txt
set +a

Jika env.txtseperti:

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

Penjelasan -a setara dengan allexport . Dengan kata lain, setiap tugas variabel dalam shell diekspor ke lingkungan (untuk digunakan oleh beberapa proses anak). Informasi lebih lanjut dapat ditemukan di dokumentasi Set builtin :

-a     Setiap variabel atau fungsi yang dibuat atau diubah diberi atribut ekspor dan ditandai untuk diekspor ke lingkungan perintah berikutnya.

Menggunakan '+' daripada '-' menyebabkan opsi ini dimatikan. Opsi-opsi ini juga dapat digunakan atas permintaan shell. Set opsi saat ini dapat ditemukan dalam $ -.

Dan Kowalczyk
sumber
Bisakah Anda menjelaskan -a dan + a?
Otto
11
@Otto -asama dengan allexport. Dengan kata lain, setiap tugas variabel dalam shell exportdiedarkan ke lingkungan (untuk digunakan oleh beberapa proses anak). Juga lihat artikel ini gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
Dan Kowalczyk
33

The allexportopsi disebutkan dalam beberapa jawaban lain di sini, yang set -amerupakan jalan pintas. Sumber .env benar-benar lebih baik daripada mengulang-ulang baris dan mengekspor karena memungkinkan komentar, baris kosong, dan bahkan variabel lingkungan yang dihasilkan oleh perintah. .Bashrc saya meliputi yang berikut ini:

# .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
sumber
3
Ini terlihat bagus, tetapi apakah Anda membongkar variabel lingkungan ketika Anda meninggalkan direktori?
Bastian Venthur
1
Saya tidak menghapus variabel, dan itu tidak pernah menjadi masalah. Aplikasi saya cenderung menggunakan nama variabel yang berbeda, dan jika ada tumpang tindih, saya akan mengosongkannya dalam .env with VAR=.
gsf
26
eval $(cat .env | sed 's/^/export /')
selvan
sumber
1
Menggunakan eval $(cat .env | sed 's/^[^$]/export /')memungkinkan Anda memiliki garis kosong untuk keterbacaan yang lebih baik.
Mario Uher
2
Saya menemukan bahwa cat .env | sed 's/^[^$]/export /'strip dari karakter awal. Yaitu untuk file yang A=foo\nB=bar\nsaya dapatkan export =foo\nexport =bar\n. Ini bekerja lebih baik untuk melewatkan baris kosong: cat .env | sed '/^$/! s/^/export /'.
Owen S.
(Saya juga mencatat demi pegolf kode UNIX yang tidak Anda butuhkan catdalam kedua kasus: eval $(sed 's/^/export /' .env)berfungsi juga.)
Owen S.
21

Saya menemukan cara yang paling efisien adalah:

export $(xargs < .env)

Penjelasan

Ketika kami memiliki .envfile seperti ini:

key=val
foo=bar

lari xargs < .envakan mendapatkankey=val foo=bar

jadi kita akan mendapatkan export key=val foo=bardan itulah yang kita butuhkan!

Batasan

  1. Itu tidak menangani kasus di mana nilai memiliki ruang di dalamnya. Perintah seperti env menghasilkan format ini. - @ Shardj
Huan
sumber
3
Itu tidak menangani kasus di mana nilai memiliki ruang di dalamnya. Perintah seperti envmenghasilkan format ini.
Shardj
19

Berikut adalah sedsolusi lain , yang tidak menjalankan eval atau memerlukan ruby:

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

Ini menambahkan ekspor, menjaga komentar pada baris yang dimulai dengan komentar.

isi .env

A=1
#B=2

sampel dijalankan

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

Saya menemukan ini sangat berguna ketika membangun file seperti itu untuk memuat dalam file unit systemd, denganEnvironmentFile .

tutuDajuju
sumber
tidak mendukung beberapa baris dalam OSX
Abdennour TOUMI
17

Saya telah memutakhirkan jawaban user4040650 karena keduanya sederhana, dan memungkinkan komentar dalam file (yaitu baris yang dimulai dengan #), yang sangat diinginkan bagi saya, karena komentar yang menjelaskan variabel dapat ditambahkan. Menulis ulang hanya dalam konteks pertanyaan awal.

Jika skrip dipanggil seperti yang ditunjukkan minientrega.sh prac1:, maka minientrega.sh dapat memiliki:

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

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

Berikut ini diambil dari dokumentasi set :

Builtin ini sangat rumit sehingga layak bagiannya sendiri. set memungkinkan Anda untuk mengubah nilai opsi shell dan mengatur parameter posisi, atau untuk menampilkan nama dan nilai variabel shell.

set [--abefhkmnptuvxBCEHPT] [-o option-name] [argumen ...] set [+ abefhkmnptuvxBCEHPT] [+ o opsi-nama] [argumen ...]

Jika tidak ada opsi atau argumen yang diberikan, set menampilkan nama dan nilai semua variabel dan fungsi shell, diurutkan sesuai dengan lokal saat ini, dalam format yang dapat digunakan kembali sebagai input untuk pengaturan atau pengaturan ulang variabel yang saat ini ditetapkan. Variabel read-only tidak dapat direset. Dalam mode POSIX, hanya variabel shell yang terdaftar.

Ketika opsi disediakan, mereka menetapkan atau membatalkan atribut shell. Opsi, jika ditentukan, memiliki arti berikut:

-a Setiap variabel atau fungsi yang dibuat atau diubah diberi atribut ekspor dan ditandai untuk diekspor ke lingkungan perintah berikutnya.

Dan ini juga:

Menggunakan '+' daripada '-' menyebabkan opsi ini dimatikan. Opsi-opsi ini juga dapat digunakan atas permintaan shell. Set opsi saat ini dapat ditemukan dalam $ -.

Nagev
sumber
14

Memperbaiki jawaban Silas Paul

mengekspor variabel pada subkulit membuatnya lokal ke perintah.

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

Jaydeep Solanki
sumber
Kemudian Anda dapat menggunakan ini (set -a; source dev.env; set +a; rails c)untuk juga memiliki manfaat sumber (mis. Skrip dapat mengeksekusi).
wacha
12

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

Ini akan menyimpan / mengembalikan opsi asli Anda, apa pun itu.

Menggunakan set -o allexportmemiliki keuntungan melewatkan komentar dengan benar tanpa regex.

set +odengan sendirinya menampilkan semua opsi Anda saat ini dalam format yang kemudian dapat dieksekusi oleh bash. Juga berguna: set -odengan sendirinya, menampilkan semua opsi Anda saat ini dalam format ramah-manusia.

jwfearn
sumber
2
Saya mungkin akan exec env -i bashmenghapus lingkungan yang ada sebelum memanggil evaljika Anda perlu menghapus variabel yang hanya diatur di dalam .env.
b4hand
11

Cara terpendek yang saya temukan:

.envFile Anda :

VARIABLE_NAME="A_VALUE"

Lalu saja

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

Bonus: Karena ini adalah one-liner pendek, itu sangat berguna dalam package.jsonfile

  "scripts": {
    "echo:variable": ". ./.env && echo ${VARIABLE_NAME}"
  }
Flavien Volken
sumber
Bagaimana kalau Anda punya banyak variabel?
Madeo
@Madeo Anda dapat menambahkan baris sebanyak yang Anda inginkan, dengan cara yang sama dengan barisVARIABLE_NAME="A_VALUE"
Flavien Volken
9

Lebih sederhana:

  1. ambil konten file
  2. hapus baris kosong (hanya jika Anda memisahkan beberapa hal)
  3. hapus semua komentar (hanya jika Anda menambahkan beberapa ...)
  4. tambahkan exportke semua baris
  5. eval secara garis besar

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

Opsi lain (Anda tidak harus menjalankan eval(terima kasih ke @Jaydeep)):

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

Terakhir, jika Anda ingin membuat hidup Anda SANGAT mudah, tambahkan ini ke ~/.bash_profile:

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

(PASTIKAN ANDA MENGEMBALIKAN PENGATURAN UANG ANDA !!! source ~/.bash_profileatau .. cukup buat tab / jendela baru dan masalah teratasi) Anda menyebutnya seperti ini:source_envfile .env

Javier Buzzi
sumber
2
Saya harus membaca .env teks dari variabel rahasia gitlab untuk pipa: Berdasarkan solusi Anda perintah ini bekerja untuk saya: source <( echo $(sed -E -n 's/[^#]+/ &/ p' <(echo "${2}" | tr -d '\r')) );. Entah bagaimana gitlab menyimpan variabel rahasia dengan windows carriage return, jadi saya harus memotongnya tr -d '\r'.
metanerd
6

Anda dapat menggunakan skrip asli untuk mengatur variabel, tetapi Anda harus menyebutnya dengan cara berikut (dengan titik yang berdiri sendiri):

. ./minientrega.sh

Mungkin juga ada masalah dengan cat | while readpendekatan. Saya akan merekomendasikan untuk menggunakan pendekatan iniwhile read line; do .... done < $FILE .

Berikut ini contoh kerjanya:

> 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
sumber
Tidak seperti kebanyakan jawaban lain, solusi ini tidak eval test.confsebagai file skrip. Itu membuatnya lebih baik. Lebih aman untuk tidak mengizinkan skrip kecuali Anda benar-benar membutuhkannya, terutama jika seseorang tidak menyadari bahwa itulah yang terjadi (atau lupa).
meustrus
5

Membangun jawaban lain, berikut adalah cara untuk mengekspor hanya sebagian dari baris dalam file, termasuk nilai dengan spasi seperti PREFIX_ONE="a word":

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

Inilah varian saya:

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

dibandingkan dengan solusi sebelumnya:

  • itu tidak bocor variabel di luar ruang lingkup (nilai-nilai dari .envtidak terkena penelepon)
  • tidak setopsi clobber
  • mengembalikan kode keluar dari perintah yang dieksekusi
  • menggunakan POSIX yang kompatibel set -a
  • menggunakan .alih-alih sourceuntuk menghindari bashism
  • perintah tidak dipanggil jika .envpemuatan gagal
with_env rails console
Elan Ruusamäe
sumber
Anda juga dapat menjalankan inline (variabel terpapar pada sesi terminal Anda saat ini): set -a && . ./.env && "$@" && echo "your comand here"
Giovanne Afonso
4

Saya bekerja dengan docker-compose dan .envfile di Mac, dan ingin mengimpor .envbash shell saya (untuk pengujian), dan jawaban "terbaik" di sini adalah tersandung pada variabel berikut:

.env

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

Larutan

Jadi saya akhirnya menggunakan eval, dan membungkus def env var saya dengan tanda kutip tunggal.

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

Versi 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
sumber
3

.Env saya:

#!/bin/bash
set -a # export all variables

#comments as usual, this is a bash script
USER=foo
PASS=bar

set +a #stop exporting variables

Memohon:

source .env; echo $USER; echo $PASS

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

Tudor Ilisoi
sumber
2

Saya memiliki masalah dengan solusi yang disarankan sebelumnya:

  • Solusi @ anubhava membuat penulisan file konfigurasi bash friendly sangat mengganggu sangat cepat, dan juga - Anda mungkin tidak ingin selalu mengekspor konfigurasi Anda.
  • Solusi @Silas Paul pecah ketika Anda memiliki variabel yang memiliki spasi atau karakter lain yang bekerja dengan baik dalam nilai-nilai yang dikutip, tetapi $()membuatnya berantakan.

Ini solusi saya, yang masih merupakan IMO yang sangat buruk - dan tidak menyelesaikan masalah "ekspor hanya untuk satu anak" yang ditangani oleh Silas (meskipun Anda mungkin dapat menjalankannya dalam sub-shell untuk membatasi ruang lingkup):

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

Persyaratan saya adalah:

  • File .env sederhana tanpa exportawalan (untuk kompatibilitas dengan dotenv)
  • nilai pendukung dalam tanda kutip: TEXT = "alpha bravo charlie"
  • komentar pendukung diawali dengan # dan baris kosong
  • universal untuk mac / BSD dan linux / GNU

Versi kerja lengkap yang disusun dari jawaban di atas:

  set -o allexport
  eval $(grep -v '^#' .env | sed 's/^/export /')
  set +o allexport
Alex
sumber
1
apa gunanya "-o allexport" jika Anda menambahkannya dengan "ekspor"?
il - ya
2

Pertama, buat file lingkungan yang akan memiliki semua pasangan kunci-nilai lingkungan seperti di bawah ini dan beri nama apa pun yang Anda suka dalam kasus saya ini env_var.env

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

Kemudian buat skrip yang akan mengekspor semua variabel lingkungan untuk lingkungan python seperti di bawah ini dan beri nama seperti itu export_env.sh

#!/usr/bin/env bash

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

set -o allexport
source $ENV_FILE
set +o allexport

$CMD

Script ini akan mengambil argumen pertama sebagai file lingkungan lalu mengekspor semua variabel lingkungan dalam file itu dan kemudian jalankan perintah setelah itu.

PEMAKAIAN:

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

Saya menemukan utas ini ketika saya mencoba menggunakan kembali Docker --env-filedi shell. Formatnya tidak kompatibel dengan bash tetapi sederhana name=value:, tanpa kutip, tanpa substitusi. Mereka juga mengabaikan garis kosong dan #komentar.

Saya tidak bisa membuatnya kompatibel dengan posix, tapi inilah yang harus bekerja di shell mirip bash (diuji di zsh pada OSX 10.12.5 dan bash di Ubuntu 14.04):

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

Itu tidak akan menangani tiga kasus dalam contoh dari dokumen yang ditautkan di atas:

  • bash: export: `123qwe=bar': not a valid identifier
  • bash: export: `org.spring.config=something': not a valid identifier
  • dan itu tidak akan menangani sintaks passthrough (telanjang FOO)
Bob Zoller
sumber
1

Spasi putih dalam nilai

Ada banyak jawaban bagus di sini, tetapi saya menemukan semuanya kurang mendukung ruang putih dalam nilai:

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

Saya telah menemukan 2 solusi yang bekerja dengan nilai-nilai tersebut dengan dukungan untuk baris dan komentar kosong.

Satu berdasarkan sed dan @ javier-buzzi menjawab :

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

Dan satu dengan membaca baris dalam satu lingkaran berdasarkan jawaban @ john1024

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

Kuncinya di sini adalah dalam menggunakan declare -xdan menempatkan garis dalam tanda kutip ganda. Saya tidak tahu mengapa tetapi ketika Anda memformat ulang kode loop ke beberapa baris itu tidak akan berhasil - Saya bukan programmer bash, saya hanya melahap bersama ini, itu masih ajaib bagi saya :)

Janusz Skonieczny
sumber
1
Saya harus memodifikasi sedsolusi untuk membuatnya berfungsi. Tetapi pertama-tama beberapa penjelasan: -ekependekan --expression, yang hanya memberi sedtahu operasi apa yang harus diambil. -e /^$/dmenghapus baris kosong dari output (bukan file). -e /^#/dmenghapus komentar bash (baris yang dimulai dengan #) dari output. 's/.*/declare -x "&"/g'mengganti (mengganti) baris yang tersisa dengan declare -x "ENV_VAR="VALUE"". Ketika Anda sumber ini, setidaknya bagi saya, itu tidak berhasil. Sebagai gantinya, saya harus menggunakan source <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x &/g' .env), untuk menghapus "bungkus tambahan .
jcasner
Saya tidak menggunakan ENV_VAR="lorem ipsum", saya punya ENV_VAR=lorem ipsum, tanpa tanda kutip di file .env. Sekarang saya tidak yakin mengapa, tapi ini mungkin bermasalah pada alat lain yang mengurai file ini. Dan bukannya lorem ipsumsaya berakhir dengan "lorem ipsum"nilai - dengan tanda kutip. Terima kasih atas penjelasannya :)
Janusz Skonieczny
1
Jika itu pilihan saya, saya tidak akan menggunakan ENV_VAR="lorem ipsum"keduanya. Dalam kasus penggunaan saya, penyedia hosting saya membuat file ini berdasarkan beberapa opsi konfigurasi yang telah saya atur, dan mereka memasukkan tanda kutip ganda. Jadi, saya terpaksa mengatasinya. Terima kasih atas bantuan Anda di sini - menghemat banyak waktu saya mencoba mencari sedpilihan yang benar sendiri!
jcasner
1

coba sesuatu seperti ini

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

Bagaimana itu bekerja

  1. Buat file temp.
  2. Tulis semua nilai variabel lingkungan saat ini ke file temp.
  3. Aktifkan ekspor semua variabel yang dideklarasikan di skrip sumber ke lingkungan.
  4. Baca .envfile. Semua variabel akan diekspor ke lingkungan saat ini.
  5. Nonaktifkan ekspor semua variabel yang dideklarasikan dalam skrip sumber ke lingkungan.
  6. Baca konten file temp. Setiap baris akan memiliki declare -x VAR="val"yang akan mengekspor masing-masing variabel ke lingkungan.
  7. Hapus file temp.
  8. Hapus pengaturan variabel yang menyimpan nama file temp.

fitur

  • Mempertahankan nilai variabel yang telah ditetapkan di lingkungan
  • .env dapat memiliki komentar
  • .env dapat memiliki garis kosong
  • .envtidak memerlukan header atau footer khusus seperti pada jawaban lainnya ( set -adan set +a)
  • .envtidak perlu memiliki exportuntuk setiap nilai
  • satu garis
Alex Skrypnyk
sumber
0

File .env saya terlihat seperti:

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

Menggunakan cara @henke , nilai yang diekspor akhirnya berisi tanda kutip"

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

Tapi saya ingin nilai yang diekspor hanya mengandung:

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

Untuk memperbaikinya, saya mengedit perintah untuk menghapus tanda kutip:

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

Yang ini mengatasi spasi pada RHS, dan melewatkan vars 'aneh' seperti definisi modul bash (dengan '()' di dalamnya):

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
sumber