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 prac1
di baris perintah itu tidak mengatur variabel lingkungan
Saya juga mencoba menggunakan source ./conf/$1
tetapi 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.
sumber
Jawaban:
Masalah dengan pendekatan Anda adalah
export
diwhile
loop sedang terjadi di sub shell, dan variabel tersebut tidak akan tersedia di shell saat ini (shell induk dari while loop).Tambahkan
export
perintah dalam file itu sendiri:Maka Anda perlu sumber dalam file di shell saat ini menggunakan:
ATAU
sumber
export
tidak ideal, masalah ini juga bisa diperbaiki dengan hanya menggunakan input redirection pada loop:while read line; do ... ; done < ./conf/$1
.< <(commands that generate output)
set -o allexport
export
akan merusaknya untuk hal-hal seperti Java, SystemD, atau alat lainawk '{print "export " $0}' envfile
perintah kenyamanan untuk menambahkan ekspor ke awal setiap barisIni mungkin membantu:
Alasan mengapa saya menggunakan ini adalah jika saya ingin menguji
.env
barang-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.
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 ):Dan jika Anda ingin
unset
semua variabel yang ditentukan dalam file, gunakan ini:Memperbarui:
Untuk juga menangani nilai dengan spasi, gunakan:
pada sistem GNU - atau:
pada sistem BSD.
sumber
export $(cat .env)
tetapi saya tidak tahu bagaimana membuat ruang itu.-d
pengaturan pembatas, jadi saya mencobaenv $(cat .env | xargs -d '\n') rails
, tetapi masih ada kesalahan dengan file yang tidak ditemukan jika.env
memiliki spasi. Adakah yang tahu mengapa ini tidak berhasil?eval $(cat .env) rails
-o allexport
memungkinkan semua definisi variabel berikut untuk diekspor.+o allexport
menonaktifkan fitur ini.sumber
.env
file memiliki komentar di dalamnya. Terima kasih!set -o allexport; source conf-file; set +o allexport
set -a; . conf-file; set +a
.Jika
env.txt
seperti: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 :
sumber
-a
sama denganallexport
. Dengan kata lain, setiap tugas variabel dalam shellexport
diedarkan ke lingkungan (untuk digunakan oleh beberapa proses anak). Juga lihat artikel ini gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlThe
allexport
opsi disebutkan dalam beberapa jawaban lain di sini, yangset -a
merupakan 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:sumber
VAR=
.sumber
eval $(cat .env | sed 's/^[^$]/export /')
memungkinkan Anda memiliki garis kosong untuk keterbacaan yang lebih baik.cat .env | sed 's/^[^$]/export /'
strip dari karakter awal. Yaitu untuk file yangA=foo\nB=bar\n
saya dapatkanexport =foo\nexport =bar\n
. Ini bekerja lebih baik untuk melewatkan baris kosong:cat .env | sed '/^$/! s/^/export /'
.cat
dalam kedua kasus:eval $(sed 's/^/export /' .env)
berfungsi juga.)Saya menemukan cara yang paling efisien adalah:
Penjelasan
Ketika kami memiliki
.env
file seperti ini:lari
xargs < .env
akan mendapatkankey=val foo=bar
jadi kita akan mendapatkan
export key=val foo=bar
dan itulah yang kita butuhkan!Batasan
sumber
env
menghasilkan format ini.Berikut adalah
sed
solusi lain , yang tidak menjalankan eval atau memerlukan ruby:Ini menambahkan ekspor, menjaga komentar pada baris yang dimulai dengan komentar.
isi .env
sampel dijalankan
Saya menemukan ini sangat berguna ketika membangun file seperti itu untuk memuat dalam file unit systemd, dengan
EnvironmentFile
.sumber
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:Berikut ini diambil dari dokumentasi set :
Dan ini juga:
sumber
Memperbaiki jawaban Silas Paul
mengekspor variabel pada subkulit membuatnya lokal ke perintah.
(export $(cat .env | xargs) && rails c)
sumber
(set -a; source dev.env; set +a; rails c)
untuk juga memiliki manfaat sumber (mis. Skrip dapat mengeksekusi).SAVE=$(set +o | grep allexport) && set -o allexport && . .env; eval "$SAVE"
Ini akan menyimpan / mengembalikan opsi asli Anda, apa pun itu.
Menggunakan
set -o allexport
memiliki keuntungan melewatkan komentar dengan benar tanpa regex.set +o
dengan sendirinya menampilkan semua opsi Anda saat ini dalam format yang kemudian dapat dieksekusi oleh bash. Juga berguna:set -o
dengan sendirinya, menampilkan semua opsi Anda saat ini dalam format ramah-manusia.sumber
exec env -i bash
menghapus lingkungan yang ada sebelum memanggileval
jika Anda perlu menghapus variabel yang hanya diatur di dalam.env
.Cara terpendek yang saya temukan:
.env
File Anda :Lalu saja
Bonus: Karena ini adalah one-liner pendek, itu sangat berguna dalam
package.json
filesumber
VARIABLE_NAME="A_VALUE"
Lebih sederhana:
export
ke semua bariseval
secara garis besareval $(cat .env | sed -e /^$/d -e /^#/d -e 's/^/export /')
Opsi lain (Anda tidak harus menjalankan
eval
(terima kasih ke @Jaydeep)):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_profile
atau .. cukup buat tab / jendela baru dan masalah teratasi) Anda menyebutnya seperti ini:source_envfile .env
sumber
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 memotongnyatr -d '\r'
.Anda dapat menggunakan skrip asli untuk mengatur variabel, tetapi Anda harus menyebutnya dengan cara berikut (dengan titik yang berdiri sendiri):
Mungkin juga ada masalah dengan
cat | while read
pendekatan. Saya akan merekomendasikan untuk menggunakan pendekatan iniwhile read line; do .... done < $FILE
.Berikut ini contoh kerjanya:
sumber
test.conf
sebagai 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).Membangun jawaban lain, berikut adalah cara untuk mengekspor hanya sebagian dari baris dalam file, termasuk nilai dengan spasi seperti
PREFIX_ONE="a word"
:sumber
Inilah varian saya:
dibandingkan dengan solusi sebelumnya:
.env
tidak terkena penelepon)set
opsi clobberset -a
.
alih-alihsource
untuk menghindari bashism.env
pemuatan gagalsumber
set -a && . ./.env && "$@" && echo "your comand here"
Saya bekerja dengan docker-compose dan
.env
file di Mac, dan ingin mengimpor.env
bash shell saya (untuk pengujian), dan jawaban "terbaik" di sini adalah tersandung pada variabel berikut:.env
Larutan
Jadi saya akhirnya menggunakan
eval
, dan membungkus def env var saya dengan tanda kutip tunggal.Versi Bash
sumber
.Env saya:
Memohon:
Referensi /unix/79068/how-to-export-variables-that-are-set-all-at-once
sumber
Saya memiliki masalah dengan solusi yang disarankan sebelumnya:
$()
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):
sumber
Persyaratan saya adalah:
export
awalan (untuk kompatibilitas dengan dotenv)Versi kerja lengkap yang disusun dari jawaban di atas:
sumber
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
Kemudian buat skrip yang akan mengekspor semua variabel lingkungan untuk lingkungan python seperti di bawah ini dan beri nama seperti itu
export_env.sh
Script ini akan mengambil argumen pertama sebagai file lingkungan lalu mengekspor semua variabel lingkungan dalam file itu dan kemudian jalankan perintah setelah itu.
PEMAKAIAN:
sumber
Saya menemukan utas ini ketika saya mencoba menggunakan kembali Docker
--env-file
di shell. Formatnya tidak kompatibel dengan bash tetapi sederhananame=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):
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
FOO
)sumber
Spasi putih dalam nilai
Ada banyak jawaban bagus di sini, tetapi saya menemukan semuanya kurang mendukung ruang putih dalam nilai:
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 :
Dan satu dengan membaca baris dalam satu lingkaran berdasarkan jawaban @ john1024
Kuncinya di sini adalah dalam menggunakan
declare -x
dan 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 :)sumber
sed
solusi untuk membuatnya berfungsi. Tetapi pertama-tama beberapa penjelasan:-e
kependekan--expression
, yang hanya memberised
tahu operasi apa yang harus diambil.-e /^$/d
menghapus baris kosong dari output (bukan file).-e /^#/d
menghapus komentar bash (baris yang dimulai dengan #) dari output.'s/.*/declare -x "&"/g'
mengganti (mengganti) baris yang tersisa dengandeclare -x "ENV_VAR="VALUE""
. Ketika Anda sumber ini, setidaknya bagi saya, itu tidak berhasil. Sebagai gantinya, saya harus menggunakansource <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x &/g' .env)
, untuk menghapus"
bungkus tambahan .ENV_VAR="lorem ipsum"
, saya punyaENV_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 bukannyalorem ipsum
saya berakhir dengan"lorem ipsum"
nilai - dengan tanda kutip. Terima kasih atas penjelasannya :)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 mencarised
pilihan yang benar sendiri!coba sesuatu seperti ini
sumber
Bagaimana itu bekerja
.env
file. Semua variabel akan diekspor ke lingkungan saat ini.declare -x VAR="val"
yang akan mengekspor masing-masing variabel ke lingkungan.fitur
.env
dapat memiliki komentar.env
dapat memiliki garis kosong.env
tidak memerlukan header atau footer khusus seperti pada jawaban lainnya (set -a
danset +a
).env
tidak perlu memilikiexport
untuk setiap nilaisumber
Jika Anda mendapatkan kesalahan karena salah satu variabel Anda berisi nilai yang berisi spasi putih Anda dapat mencoba mengatur ulang bash
IFS
(Pemisah Bidang Internal)\n
agar membiarkan bash menginterpretasikancat .env
hasil sebagai daftar parameter untukenv
dieksekusi.Contoh:
Lihat juga:
sumber
File .env saya terlihat seperti:
Menggunakan cara @henke , nilai yang diekspor akhirnya berisi tanda kutip
"
Tapi saya ingin nilai yang diekspor hanya mengandung:
Untuk memperbaikinya, saya mengedit perintah untuk menghapus tanda kutip:
sumber
Yang ini mengatasi spasi pada RHS, dan melewatkan vars 'aneh' seperti definisi modul bash (dengan '()' di dalamnya):
sumber