Đặt biến môi trường từ tệp của cặp khóa / giá trị


513

TL; DR: Làm cách nào để xuất một tập hợp các cặp khóa / giá trị từ tệp văn bản vào môi trường shell?


Đối với hồ sơ, dưới đây là phiên bản gốc của câu hỏi, với các ví dụ.

Tôi đang viết một tập lệnh trong bash để phân tích các tệp có 3 biến trong một thư mục nhất định, đây là một trong số chúng:

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

Tập tin này được lưu trữ trong ./conf/prac1

Tập lệnh của tôi minientrega.sh sau đó phân tích tệp bằng mã này:

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

Nhưng khi tôi thực thi minientrega.sh prac1trong dòng lệnh thì nó không đặt các biến môi trường

Tôi cũng đã thử sử dụng source ./conf/$1nhưng vấn đề tương tự vẫn được áp dụng

Có lẽ có một số cách khác để làm điều này, tôi chỉ cần sử dụng các biến môi trường của tệp tôi chuyển làm đối số của tập lệnh của tôi.



Tương tự với Ruby: stackoverflow.com/questions/2139080/ , một viên ngọc làm điều đó: github.com/bkeepers/dotenv
Ciro Santilli 冠状 病 六四 事件

Đây là một câu hỏi hay nhưng được đặt theo cách quá cụ thể, với các tên biến cụ thể ("MINIENTREGA_FECHALIMITE"? Điều đó có nghĩa là gì?) Và các số (3). Câu hỏi chung chỉ đơn giản là "Làm cách nào để xuất một tập hợp các cặp khóa / giá trị từ tệp văn bản vào môi trường shell".
Dan Dascalescu

Ngoài ra, điều này đã được trả lời trên unix.SE và được cho là nhiều hơn về chủ đề ở đó.
Dan Dascalescu

Câu trả lời:


209

Vấn đề với cách tiếp cận của bạn là exporttrong whilevòng lặp đang xảy ra trong một vỏ phụ, và những biến sẽ không có sẵn trong shell hiện hành (vỏ mẹ của vòng lặp while).

Thêm exportlệnh trong chính tệp:

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

Sau đó, bạn cần nguồn trong tệp trong shell hiện tại bằng cách sử dụng:

. ./conf/prac1

HOẶC LÀ

source ./conf/prac1

4
Mặc dù đọc từng dòng tệp và chuyển từng dòng đến exportkhông lý tưởng, vấn đề cũng có thể được khắc phục bằng cách sử dụng chuyển hướng đầu vào trên vòng lặp : while read line; do ... ; done < ./conf/$1.
chepner

4
Và nếu nó không phải từ một tập tin, hãy sử dụng< <(commands that generate output)
o11c

5
Bạn có một giải pháp sạch hơn , tôi có một ưu tiên choset -o allexport
heralight

2
Nếu sử dụng tệp .env này giữa các hệ thống, việc chèn exportsẽ phá vỡ nó cho những thứ như Java, SystemD hoặc các công cụ khác
FilBot3

1
awk '{print "export " $0}' envfilelệnh tiện lợi để tiếp tục xuất khẩu vào đầu mỗi dòng
Shardj

888

Điều này có thể hữu ích:

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

Lý do tại sao tôi sử dụng điều này là nếu tôi muốn kiểm tra .envcông cụ trong bảng điều khiển rails của mình.

gabrielf đã đưa ra một cách tốt để giữ các biến cục bộ. Điều này giải quyết vấn đề tiềm năng khi đi từ dự án này sang dự án khác.

env $(cat .env | xargs) rails

Tôi đã thử nghiệm điều này với bash 3.2.51(1)-release


Cập nhật:

Để bỏ qua các dòng bắt đầu bằng #, hãy sử dụng dòng này (nhờ nhận xét của Pete ):

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

Và nếu bạn muốn unsettất cả các biến được xác định trong tệp, hãy sử dụng:

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

Cập nhật:

Để xử lý các giá trị có khoảng trắng, sử dụng:

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

trên các hệ thống GNU - hoặc:

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

trên các hệ thống BSD.


6
Cảm ơn, tôi thích điều này không yêu cầu phải thêm bất cứ điều gì vào tệp - cho phép tương thích với định dạng .env của Foreman (Procfile).
natevw

29
Tôi đã đưa ra giải pháp: env $ (cat .env | xargs) rails
gabrielf

4
Điều này dường như không hoạt động nếu bất kỳ giá trị env nào có khoảng trắng, mặc dù tôi không thực sự chắc chắn cách tốt nhất / mong muốn để chỉ định giá trị với khoảng trắng là gì. github.com/ddollar/foreman/issues/56 nói rằng nó sẽ hoạt động như thế nào export $(cat .env)nhưng tôi không biết làm thế nào để giải quyết vấn đề đó với không gian.
Dan Benamy

6
@BenjaminWheeler GNU linux có -dđể thiết lập dấu phân cách, vì vậy tôi đang thử env $(cat .env | xargs -d '\n') rails, nhưng nó vẫn bị lỗi với một tệp không tìm thấy nếu .envcó khoảng trắng. Bất cứ ý tưởng tại sao điều này không làm việc?
Bailey Parker

19
Đây là một biến thể ngắn hơneval $(cat .env) rails
manalang

413

-o allexportcho phép tất cả các định nghĩa biến sau đây được xuất khẩu. +o allexportvô hiệu hóa tính năng này.

set -o allexport
source conf-file
set +o allexport

9
Hoạt động như một lá bùa! Ngay cả khi .envtập tin có ý kiến ​​trong đó. Cảm ơn!
Slava Fomin II

9
Và trong một dòngset -o allexport; source conf-file; set +o allexport
HarlemSquirrel

1
Đây là một cách tuyệt vời để đọc trong tệp thuộc tính, khi trình cắm EnvInject của Jenkins không hoạt động. Cảm ơn!
Teresa Peters

21
@CMCDragonkai, đối với POSIX, nó sẽ như vậy set -a; . conf-file; set +a.
Charles Duffy

3
Phương pháp này hoạt động nếu các biến môi trường có không gian trong đó. Nhiều người khác thì không. Trong khi phương thức eval () thực hiện, tôi cũng có một chút kỳ lạ bằng cách sử dụng eval
CommandZ

138
set -a
. ./env.txt
set +a

Nếu env.txtlà như:

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

Giải thích -a tương đương với allexport . Nói cách khác, mọi phép gán biến trong shell được xuất ra môi trường (được sử dụng bởi nhiều tiến trình con). Thông tin thêm có thể được tìm thấy trong tài liệu Setin dựng sẵn :

-a     Mỗi biến hoặc chức năng được tạo hoặc sửa đổi được đưa ra thuộc tính xuất và được đánh dấu để xuất sang môi trường của các lệnh tiếp theo.

Sử dụng '+' thay vì '-' khiến các tùy chọn này bị tắt. Các tùy chọn cũng có thể được sử dụng khi gọi vỏ. Tập hợp các tùy chọn hiện tại có thể được tìm thấy bằng $ -.


Bạn có thể giải thích -a và + a không?
Otto

11
@Otto -atương đương với allexport. Nói cách khác, mọi phép gán biến trong shell được exported vào môi trường (được sử dụng bởi nhiều tiến trình con). Ngoài ra, hãy xem bài viết này gnu.org/software/bash/manual/html_node/The-set-Builtin.html
Dan

33

Các allexporttùy chọn được đề cập trong một vài câu trả lời khác ở đây, mà set -alà các phím tắt. Tìm nguồn .env thực sự tốt hơn là lặp qua các dòng và xuất vì nó cho phép nhận xét, dòng trống và thậm chí các biến môi trường được tạo bởi các lệnh. .Bashrc của tôi bao gồm:

# .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
}

3
Điều này có vẻ tốt, nhưng bạn có tải các biến môi trường khi bạn rời khỏi thư mục?
Bastian Venthur

1
Tôi không đặt các biến và nó không bao giờ là vấn đề. Các ứng dụng của tôi có xu hướng sử dụng các tên biến khác biệt và nếu có sự trùng lặp, tôi sẽ đặt chúng thành trống trong .env với VAR=.
gsf

26
eval $(cat .env | sed 's/^/export /')

1
Sử dụng eval $(cat .env | sed 's/^[^$]/export /')cho phép bạn có các dòng trống để dễ đọc hơn.
Mario Uher

2
Tôi tìm thấy cat .env | sed 's/^[^$]/export /'dải đó ra khỏi nhân vật ban đầu. Tức là cho một tập tin A=foo\nB=bar\ntôi nhận được export =foo\nexport =bar\n. Điều này hoạt động tốt hơn để bỏ qua các dòng trống : cat .env | sed '/^$/! s/^/export /'.
Owen S.

(Tôi cũng lưu ý vì lợi ích của những người chơi golf mã UNIX mà bạn không cần cattrong cả hai trường hợp: cũng eval $(sed 's/^/export /' .env)hoạt động tốt.)
Owen S.

21

Tôi tìm thấy cách hiệu quả nhất là:

export $(xargs < .env)

Giải trình

Khi chúng tôi có một .envtập tin như thế này:

key=val
foo=bar

chạy xargs < .envsẽ nhận đượckey=val foo=bar

vì vậy chúng tôi sẽ nhận được export key=val foo=barvà đó chính xác là những gì chúng tôi cần!

Giới hạn

  1. Nó không xử lý các trường hợp trong đó các giá trị có khoảng trắng trong đó. Các lệnh như env tạo ra định dạng này. - @Shardj

3
Nó không xử lý các trường hợp trong đó các giá trị có khoảng trắng trong đó. Các lệnh như envsản xuất định dạng này.
Shardj

19

Đây là một sedgiải pháp khác , không chạy eval hoặc yêu cầu ruby:

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

Điều này thêm xuất khẩu, giữ bình luận trên các dòng bắt đầu với một bình luận.

nội dung .env

A=1
#B=2

chạy mẫu

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

Tôi thấy điều này đặc biệt hữu ích khi xây dựng một tệp như vậy để tải trong tệp đơn vị systemd, vớiEnvironmentFile .


không hỗ trợ nhiều dòng trong OSX
Abdennour TOUMI

17

Tôi đã nâng cao câu trả lời của user4040650 vì nó vừa đơn giản, vừa cho phép nhận xét trong tệp (tức là các dòng bắt đầu bằng #), rất đáng để tôi, vì các bình luận giải thích các biến có thể được thêm vào. Chỉ cần viết lại trong bối cảnh của câu hỏi ban đầu.

Nếu tập lệnh được gọi như được chỉ định : minientrega.sh prac1, thì minientrega.sh có thể có:

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

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

Sau đây được trích xuất từ tài liệu thiết lập :

Nội dung này phức tạp đến mức nó xứng đáng với phần riêng của nó. set cho phép bạn thay đổi các giá trị của các tùy chọn shell và đặt các tham số vị trí hoặc để hiển thị tên và giá trị của các biến shell.

đặt [--abefhkmnptuvxBCEHPT] [-o tùy chọn-tên] [đối số]] [+ abefhkmnptuvxBCEHPT] [+ o tên tùy chọn] [đối số]

Nếu không có tùy chọn hoặc đối số nào được cung cấp, set sẽ hiển thị tên và giá trị của tất cả các biến và hàm shell, được sắp xếp theo ngôn ngữ hiện tại, theo định dạng có thể được sử dụng lại làm đầu vào để đặt hoặc đặt lại các biến hiện được đặt. Các biến chỉ đọc không thể được đặt lại. Trong chế độ POSIX, chỉ các biến shell được liệt kê.

Khi các tùy chọn được cung cấp, chúng đặt hoặc bỏ đặt các thuộc tính shell. Tùy chọn, nếu được chỉ định, có các ý nghĩa sau:

-a Mỗi biến hoặc chức năng được tạo hoặc sửa đổi được đưa ra thuộc tính xuất và được đánh dấu để xuất sang môi trường của các lệnh tiếp theo.

Và điều này cũng vậy:

Sử dụng '+' thay vì '-' khiến các tùy chọn này bị tắt. Các tùy chọn cũng có thể được sử dụng khi gọi vỏ. Tập hợp các tùy chọn hiện tại có thể được tìm thấy bằng $ -.


14

Cải thiện câu trả lời của Silas Paul

xuất các biến trên một lớp con làm cho chúng cục bộ vào lệnh.

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


Sau đó, bạn có thể sử dụng điều này (set -a; source dev.env; set +a; rails c)để có những lợi ích của việc tìm nguồn cung ứng (ví dụ tập lệnh có thể thực thi).
wacha

12

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

Điều này sẽ lưu / khôi phục các tùy chọn ban đầu của bạn, bất kể chúng có thể là gì.

Sử dụng set -o allexport có lợi thế của việc bỏ qua các bình luận đúng cách mà không cần regex.

set +obằng chính nó xuất ra tất cả các tùy chọn hiện tại của bạn ở định dạng mà bash sau này có thể thực thi. Cũng tiện dụng: set -otự nó, xuất ra tất cả các tùy chọn hiện tại của bạn ở định dạng thân thiện với con người.


2
Tôi có thể exec env -i bashsẽ xóa môi trường hiện tại trước khi gọi evalnếu bạn cần hủy đặt các biến chỉ được đặt trong .env.
b4hand

11

Cách ngắn nhất tôi tìm thấy:

.envTập tin của bạn :

VARIABLE_NAME="A_VALUE"

Sau đó chỉ

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

Phần thưởng: Bởi vì nó là một lớp lót ngắn, nên nó rất hữu ích trong package.jsontệp

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

Làm thế nào về nếu bạn có rất nhiều biến?
Madeo

@Madeo bạn có thể thêm bao nhiêu dòng tùy thích, giống như dòngVARIABLE_NAME="A_VALUE"
Flavien Volken

9

Đơn giản hơn:

  1. lấy nội dung của tập tin
  2. xóa bất kỳ dòng trống nào (chỉ cần bạn tách một số thứ)
  3. xóa mọi bình luận (chỉ cần bạn thêm một số ...)
  4. thêm exportvào tất cả các dòng
  5. eval toàn bộ

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

Một tùy chọn khác (bạn không phải chạy eval(nhờ @Jaydeep)):

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

Cuối cùng, nếu bạn muốn làm cho cuộc sống của mình THỰC SỰ dễ dàng, hãy thêm điều này vào ~/.bash_profile:

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

(HÃY ĐỂ BẠN THAM GIA CÀI ĐẶT TIỀN CỦA BẠN !!! source ~/.bash_profilehoặc .. chỉ cần tạo một tab / cửa sổ mới và giải quyết vấn đề) bạn gọi nó như thế này:source_envfile .env


2
Tôi đã phải đọc văn bản .env từ biến bí mật gitlab cho một đường ống: Dựa trên giải pháp của bạn, lệnh này đã làm việc cho tôi : source <( echo $(sed -E -n 's/[^#]+/ &/ p' <(echo "${2}" | tr -d '\r')) );. Bằng cách nào đó gitlab lưu biến bí mật với lợi nhuận của cửa sổ vận chuyển, vì vậy tôi phải cắt nó với tr -d '\r'.
metanerd

6

Bạn có thể sử dụng tập lệnh gốc của mình để đặt các biến, nhưng bạn cần gọi nó theo cách sau (với dấu chấm độc lập):

. ./minientrega.sh

Ngoài ra có thể có một vấn đề với cat | while readcách tiếp cận. Tôi muốn giới thiệu để sử dụng các phương pháp while read line; do .... done < $FILE.

Dưới đây là một ví dụ hoạt động:

> 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

Không giống như hầu hết các câu trả lời khác, giải pháp này không phải test.conflà một tập lệnh. Điều đó làm cho nó tốt hơn. Sẽ an toàn hơn khi không cho phép viết kịch bản trừ khi bạn thực sự cần nó, đặc biệt nếu ai đó không nhận ra điều đó đang xảy ra (hoặc quên).
meustrus

5

Dựa trên các câu trả lời khác, đây là cách chỉ xuất một tập hợp con các dòng trong tệp, bao gồm các giá trị có khoảng trắng như PREFIX_ONE="a word":

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

5

Đây là biến thể của tôi:

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

so với các giải pháp trước đây:

  • nó không rò rỉ các biến ngoài phạm vi (các giá trị từ .envkhông được hiển thị cho người gọi)
  • không settùy chọn clobber
  • trả về mã thoát của lệnh đã thực hiện
  • sử dụng tương thích posix set -a
  • sử dụng .thay vì sourceđể tránh bashism
  • lệnh không được gọi nếu .envtải thất bại
with_env rails console

Bạn cũng có thể chạy nội tuyến (các biến được hiển thị cho phiên cuối cùng hiện tại của bạn): set -a && . ./.env && "$@" && echo "your comand here"
Giovanne Afonso

4

Tôi làm việc với docker-compose và .envcác tệp trên Mac và muốn nhập tệp .envbash shell của mình (để thử nghiệm) và câu trả lời "tốt nhất" ở đây là vấp phải biến sau:

.env

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

Giải pháp

Vì vậy, tôi đã kết thúc việc sử dụng evalvà gói env var defs của tôi trong dấu ngoặc đơn.

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

Phiên bản Bash

$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.


2

Tôi có vấn đề với các giải pháp được đề xuất trước đó:

  • Giải pháp của @ anubhava làm cho việc viết các tệp cấu hình thân thiện bash rất khó chịu rất nhanh và cũng có thể - bạn có thể không muốn luôn xuất cấu hình của mình.
  • Giải pháp @Silas Paul bị hỏng khi bạn có các biến có khoảng trắng hoặc các ký tự khác hoạt động tốt trong các giá trị được trích dẫn, nhưng $()làm cho một mớ hỗn độn biến mất.

Đây là giải pháp của tôi, IMO vẫn còn khá khủng khiếp - và không giải quyết được vấn đề "chỉ xuất khẩu cho một đứa trẻ" được giải quyết bởi Silas (mặc dù bạn có thể chạy nó trong một vỏ phụ để giới hạn phạm vi):

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

2

Yêu cầu của tôi là:

  • tệp .env đơn giản không có exporttiền tố (để tương thích với dotenv)
  • giá trị hỗ trợ trong dấu ngoặc kép: TEXT = "alpha bravo charlie"
  • hỗ trợ bình luận có tiền tố # và dòng trống
  • phổ quát cho cả mac / BSD và linux / GNU

Phiên bản làm việc đầy đủ được tổng hợp từ các câu trả lời ở trên:

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

1
điểm của "-o allexport" là gì nếu bạn đăng ký trước chúng bằng "xuất khẩu"?
il - ya

2

Đầu tiên, tạo một tệp môi trường sẽ có tất cả các cặp giá trị khóa của các môi trường như bên dưới và đặt tên nó là bất cứ thứ gì bạn thích trong trường hợp của tôi env_var.env

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

Sau đó, tạo một tập lệnh sẽ xuất tất cả các biến môi trường cho môi trường python như bên dưới và đặt tên như thế export_env.sh

#!/usr/bin/env bash

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

set -o allexport
source $ENV_FILE
set +o allexport

$CMD

Kịch bản lệnh này sẽ lấy đối số đầu tiên làm tệp môi trường sau đó xuất tất cả biến môi trường trong tệp đó và sau đó chạy lệnh sau đó.

SỬ DỤNG:

./export_env.sh env_var.env python app.py

1

Tôi đã bắt gặp chủ đề này khi tôi đang thử sử dụng lại Docker --env-filetrong một cái vỏ. Định dạng của chúng không tương thích bash nhưng nó đơn giản : name=value, không trích dẫn, không thay thế. Họ cũng bỏ qua những dòng trống và #bình luận.

Tôi hoàn toàn không thể có được nó tương thích posix, nhưng đây là một cái nên hoạt động trong các shell giống như bash (được thử nghiệm trong zsh trên OSX 10.12.5 và bash trên Ubuntu 14.04):

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

sẽ không xử lý ba trường hợp trong ví dụ từ các tài liệu được liên kết ở trên:

  • bash: export: `123qwe=bar': not a valid identifier
  • bash: export: `org.spring.config=something': not a valid identifier
  • và nó sẽ không xử lý cú pháp thông qua (trần FOO)

1

Khoảng trắng trong giá trị

Có nhiều câu trả lời tuyệt vời ở đây, nhưng tôi thấy tất cả chúng đều thiếu sự hỗ trợ cho khoảng trắng trong giá trị:

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

Tôi đã tìm thấy 2 giải pháp hoạt động với các giá trị như vậy với sự hỗ trợ cho các dòng và nhận xét trống.

Một dựa trên câu trả lời của sed và @ javier-buzzi :

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

Và một với dòng đọc trong một vòng lặp dựa trên câu trả lời @ john1024

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

Chìa khóa ở đây là trong việc sử dụng declare -xvà đặt dòng trong dấu ngoặc kép. Tôi không biết tại sao nhưng khi bạn định dạng lại mã vòng lặp thành nhiều dòng thì nó sẽ không hoạt động - Tôi không phải là người lập trình bash, tôi chỉ ngấu nghiến những thứ này, nó vẫn là phép màu đối với tôi :)


1
Tôi đã phải sửa đổi sedgiải pháp để làm cho nó hoạt động. Nhưng trước tiên một số giải thích: -elà viết tắt của --expression, nó chỉ cho biết sednhững hoạt động cần thực hiện. -e /^$/dxóa các dòng trống từ đầu ra (không phải tệp). -e /^#/dxóa các bình luận bash (dòng bắt đầu bằng #) khỏi đầu ra. 's/.*/declare -x "&"/g'thay thế (thay thế) các dòng còn lại bằng declare -x "ENV_VAR="VALUE"". Khi bạn lấy nguồn này, ít nhất là đối với tôi, nó không hoạt động. Thay vào đó, tôi phải sử dụng source <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x &/g' .env), để loại bỏ lớp "bọc thêm .
jcasner

Tôi không sử dụng ENV_VAR="lorem ipsum", tôi có ENV_VAR=lorem ipsum, không có dấu ngoặc kép trong tệp .env. Bây giờ tôi không chắc tại sao, nhưng điều này có lẽ có vấn đề trong các công cụ khác phân tích tệp này. Và thay vì lorem ipsumtôi đã kết thúc với "lorem ipsum"giá trị - với dấu ngoặc kép. Thx cho lời giải thích :)
Janusz Skonieczny

1
Nếu đó là lựa chọn của tôi, tôi cũng sẽ không sử dụng ENV_VAR="lorem ipsum". Trong trường hợp sử dụng của tôi, nhà cung cấp dịch vụ lưu trữ của tôi tạo tệp này dựa trên một số tùy chọn cấu hình tôi đã đặt và họ chèn dấu ngoặc kép. Vì vậy, tôi buộc phải làm việc xung quanh nó. Cảm ơn sự giúp đỡ của bạn ở đây - đã tiết kiệm cho tôi rất nhiều thời gian cố gắng tự mình tìm ra các sedlựa chọn chính xác !
jcasner

1

thử cái gì đó như thế này

for line in `cat your_env_file`; do if [[ $line != \#* ]];then export $line; fi;done

1
t=$(mktemp) && export -p > "$t" && set -a && . ./.env && set +a && . "$t" && rm "$t" && unset t

Làm thế nào nó hoạt động

  1. Tạo tập tin tạm thời.
  2. Viết tất cả các giá trị biến môi trường hiện tại vào tệp tạm thời.
  3. Cho phép xuất tất cả các biến được khai báo trong tập lệnh nguồn ra môi trường.
  4. Đọc .envtập tin. Tất cả các biến sẽ được xuất vào môi trường hiện tại.
  5. Vô hiệu hóa xuất tất cả các biến được khai báo trong tập lệnh nguồn ra môi trường.
  6. Đọc nội dung của tệp tạm thời. Mỗi dòng sẽ có declare -x VAR="val"điều đó sẽ xuất từng biến vào môi trường.
  7. Xóa tệp tạm thời.
  8. Bỏ đặt biến giữ tên tệp tạm thời.

Đặc trưng

  • Giữ nguyên giá trị của các biến đã được đặt trong môi trường
  • .env có thể có ý kiến
  • .env có thể có dòng trống
  • .envkhông yêu cầu tiêu đề hoặc chân trang đặc biệt như trong các câu trả lời khác ( set -aset +a)
  • .envkhông yêu cầu phải có exportcho mọi giá trị
  • lót

0

Nếu bạn gặp lỗi vì một trong các biến của bạn chứa giá trị chứa khoảng trắng, bạn có thể thử đặt lại bash's IFS(Dấu tách trường nội bộ) để \ncho phép bash diễn giải cat .envkết quả dưới dạng danh sách các tham số cho envtệp thực thi.

Thí dụ:

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

Xem thêm:


0

Tệp .env của tôi trông như:

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

Sử dụng các cách của @henke , giá trị đã xuất kết thúc có chứa dấu ngoặc kép"

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

Nhưng tôi muốn giá trị xuất chỉ chứa:

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

Để sửa nó, tôi chỉnh sửa lệnh để xóa dấu ngoặc kép:

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

0

Cái này đối phó với khoảng trắng trên RHS và bỏ qua các vars 'lạ' như định nghĩa mô-đun bash (có '()' trong đó):

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.