815

TL;DR:如何将一组键/值对从文本文件导出到 shell 环境中?


作为记录,以下是问题的原始版本,并附有示例。

我正在用 bash 编写一个脚本,它在某个文件夹中解析具有 3 个变量的文件,这是其中之一:

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

该文件存储在./conf/prac1

然后我的脚本minientrega.sh使用以下代码解析文件:

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

但是当我minientrega.sh prac1在命令行中执行它并没有设置环境变量

我也尝试过使用source ./conf/$1,但同样的问题仍然适用

也许还有其他方法可以做到这一点,我只需要使用我传递的文件的环境变量作为脚本的参数。

4

43 回答 43

1233

这可能会有所帮助:

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

我使用它的原因是如果我想.env在我的 rails 控制台中测试东西。

gabrielf想出了一个将变量保持在本地的好方法。这解决了从一个项目到另一个项目时的潜在问题。

env $(cat .env | xargs) rails

我已经测试过了bash 3.2.51(1)-release


更新:

要忽略以 开头的行#,请使用它(感谢Pete 的评论):

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

如果您想要unset文件中定义的所有变量,请使用以下命令:

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

更新:

要同时处理带有空格的值,请使用:

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

在 GNU 系统上——或者:

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

在 BSD 系统上。


这个答案中,您可以使用以下方法自动检测操作系统:

export-env.sh

#!/bin/sh

## Usage:
##   . ./export-env.sh ; $COMMAND
##   . ./export-env.sh ; echo ${MINIENTREGA_FECHALIMITE}

unamestr=$(uname)
if [ "$unamestr" = 'Linux' ]; then

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

elif [ "$unamestr" = 'FreeBSD' ]; then

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

fi

于 2014-01-03T17:10:10.787 回答
682

-o allexport允许导出所有以下变量定义。+o allexport禁用此功能。

set -o allexport
source conf-file
set +o allexport
于 2015-06-21T22:03:41.960 回答
308

您的方法的问题是export循环while中发生在子外壳中,并且这些变量在当前外壳(while 循环的父外壳)中不可用。

export在文件本身中添加命令:

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

然后,您需要使用以下命令在当前 shell 中获取文件:

. ./conf/prac1

或者

source ./conf/prac1
于 2013-10-12T07:05:03.153 回答
251
set -a
. ./env.txt
set +a

如果env.txt是这样的:

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

说明 -a 等价于allexport。换句话说,shell 中的每个变量分配都被导出到环境中(供多个子进程使用)。更多信息可以在Set 内置文档中找到:

-a     创建或修改的每个变量或函数都被赋予导出属性并标记为导出到后续命令的环境。

使用“+”而不是“-”会导致这些选项被关闭。这些选项也可以在调用 shell 时使用。当前的选项集可以在 $- 中找到。

于 2017-08-30T23:34:22.723 回答
68

我发现最有效的方法是:

export $(xargs < .env)

解释

当我们有这样的.env文件时:

key=val
foo=bar

运行xargs < .env会得到key=val foo=bar

所以我们会得到一个export key=val foo=bar,这正是我们需要的!

局限性

  1. 它不处理值中有空格的情况。诸如 env 之类的命令会产生这种格式。– @Shardj
于 2020-02-26T04:30:47.893 回答
43

allexport此处的其他几个答案中提到了该选项,这set -a是快捷方式。获取 .env 确实比遍历行和导出要好,因为它允许注释、空行,甚至是命令生成的环境变量。我的 .bashrc 包括以下内容:

# .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
}
于 2015-12-04T16:57:59.167 回答
29
eval $(cat .env | sed 's/^/export /')
于 2015-04-07T09:49:19.753 回答
27

这是另一个sed解决方案,它不运行 eval 或需要 ruby​​:

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

这增加了导出,将注释保留在以注释开头的行上。

.env 内容

A=1
#B=2

样品运行

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

我发现这在构建这样的文件以加载到systemd 单元文件时特别有用,使用EnvironmentFile.

于 2016-04-06T16:21:58.853 回答
22

问题source在于它要求文件具有正确的 bash 语法,并且一些特殊字符会破坏它:=, ", ', <,>等。所以在某些情况下你可以

source development.env

它会起作用。

但是,此版本可以承受值中的每个特殊字符

set -a
source <(cat development.env | \
    sed -e '/^#/d;/^\s*$/d' -e "s/'/'\\\''/g" -e "s/=\(.*\)/='\1'/g")
set +a

解释:

  • -a意味着每个 bash 变量都将成为环境变量
  • /^#/d删除注释(以 开头的字符串#
  • /^\s*$/d删除空字符串,包括空格
  • "s/'/'\\\''/g"用 替换每个单引号'\'',这是 bash 中产生引号的技巧序列 :)
  • "s/=\(.*\)/='\1'/g"将每个a=b转换为a='b'

结果,您可以使用特殊字符:)

要调试此代码,请替换sourcecat,您将看到此命令产生的内容。

于 2021-02-09T11:21:40.260 回答
20

我赞成 user4040650 的答案,因为它既简单又允许在文件中添加注释(即以 # 开头的行),这对我来说是非常可取的,因为可以添加解释变量的注释。只是在原始问题的上下文中重写。

如果脚本按指示调用:minientrega.sh prac1,则 minientrega.sh 可能具有:

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

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

以下内容是从集合文档中提取的:

这个内置函数非常复杂,值得拥有自己的部分。set 允许您更改 shell 选项的值并设置位置参数,或显示 shell 变量的名称和值。

设置 [--abefhkmnptuvxBCEHPT] [-o 选项名称] [参数 ...] 设置 [+abefhkmnptuvxBCEHPT] [+o 选项名称] [参数 ...]

如果没有提供选项或参数,set 会显示所有 shell 变量和函数的名称和值,按照当前语言环境排序,格式可重复用作设置或重置当前设置变量的输入。只读变量不能被重置。在 POSIX 模式下,仅列出 shell 变量。

提供选项时,它们会设置或取消设置 shell 属性。选项(如果指定)具有以下含义:

-a 创建或修改的每个变量或函数都被赋予导出属性并标记为导出到后续命令的环境。

这也是:

使用“+”而不是“-”会导致这些选项被关闭。这些选项也可以在调用 shell 时使用。当前的选项集可以在 $- 中找到。

于 2017-03-08T11:46:05.497 回答
18

不完全确定为什么,或者我错过了什么,但是在运行了大多数答案并失败之后。我意识到这个 .env 文件:

MY_VAR="hello there!"
MY_OTHER_VAR=123

我可以简单地这样做:

source .env
echo $MY_VAR

输出:Hello there!

似乎在 Ubuntu linux 中工作得很好。

于 2020-08-06T06:33:48.323 回答
17

改进 Silas Paul 的回答

将变量导出到子shell 会使它们成为命令的本地变量。

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

于 2015-10-21T20:37:00.653 回答
16

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

这将保存/恢复您的原始选项,无论它们是什么。

Usingset -o allexport的优点是可以在没有正则表达式的情况下正确跳过注释。

set +o它本身以 bash 以后可以执行的格式输出所有当前选项。也很方便:set -o它本身会以人性化的格式输出您当前的所有选项。

于 2015-09-09T20:57:56.433 回答
14

这是我的变体:

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

与之前的解决方案相比:

  • 它不会泄漏范围外的变量(来自.env的值不会暴露给调用者)
  • 不会破坏set选项
  • 返回执行命令的退出代码
  • 使用 posix 兼容set -a
  • 使用.而不是source避免bashism
  • .env如果加载失败,则不会调用命令
with_env rails console
于 2020-01-22T14:24:38.740 回答
13

我发现的最短方法:

你的.env文件:

VARIABLE_NAME="A_VALUE"

然后就

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

奖励:因为它是一个短的单行,它在package.json文件中非常有用

  "scripts": {
    "echo:variable": ". ./.env && echo ${VARIABLE_NAME}"
  }
于 2019-05-28T10:56:39.387 回答
10

更简单:

  1. 抓取文件的内容
  2. 删除任何空行(以防你分开一些东西)
  3. 删除任何评论(以防你添加了一些......)
  4. 添加export到所有行
  5. eval整个东西

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

另一种选择(您不必运行eval(感谢@Jaydeep)):

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

最后,如果您想让您的生活变得非常轻松,请将其添加到您的~/.bash_profile

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

(确保您重新加载您的 BASH 设置!!!source ~/.bash_profile或者.. 只需创建一个新选项卡/窗口并解决问题)您可以这样称呼它:source_envfile .env

于 2017-09-13T14:05:36.240 回答
9

如果env支持该-S选项,则可以使用换行符或转义字符,例如\nor \t(参见env):

env -S "$(cat .env)" command

.env文件示例:

KEY="value with space\nnewline\ttab\tand
multiple
lines"

测试:

env -S "$(cat .env)" sh -c 'echo "$KEY"'
于 2020-12-31T10:09:29.013 回答
8

我在 Mac 上使用 docker-compose 和.env文件,并希望将其.env导入我的 bash shell(用于测试),这里的“最佳”答案是在以下变量上绊倒:

.env

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

解决方案

所以我最终使用eval, 并将我的 env var defs 用单引号括起来。

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

重击版本

$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.
于 2019-05-20T22:39:45.670 回答
7

您可以使用原始脚本来设置变量,但您需要通过以下方式调用它(使用独立点):

. ./minientrega.sh

方法也可能存在问题cat | while read。我建议使用该方法while read line; do .... done < $FILE

这是一个工作示例:

> 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
于 2014-02-17T14:29:54.320 回答
7
t=$(mktemp) && export -p > "$t" && set -a && . ./.env && set +a && . "$t" && rm "$t" && unset t

这个怎么运作

  1. 创建临时文件。
  2. 将所有当前环境变量值写入临时文件。
  3. 启用将源脚本中所有声明的变量导出到环境。
  4. 读取.env文件。所有变量都将导出到当前环境中。
  5. 禁止将源脚本中所有声明的变量导出到环境。
  6. 读取临时文件的内容。每一行都会declare -x VAR="val"将每个变量导出到环境中。
  7. 删除临时文件。
  8. 取消设置保存临时文件名的变量。

特征

  • 保留环境中已设置的变量值
  • .env可以有评论
  • .env可以有空行
  • .env不需要像其他答案(set -aset +a)中那样的特殊页眉或页脚
  • .env不需要export对每个值都有
  • 单线
于 2020-01-20T22:17:23.270 回答
6

在其他答案的基础上,这是一种仅导出文件中行子集的方法,包括带有空格的值,例如PREFIX_ONE="a word"

set -a
. <(grep '^[ ]*PREFIX_' conf-file)
set +a
于 2017-03-09T00:44:25.870 回答
5

我的.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

调用:

source .env; echo $USER; echo $PASS

参考https://unix.stackexchange.com/questions/79068/how-to-export-variables-that-are-set-all-at-once

于 2017-05-26T00:28:30.453 回答
5

使用 shdotenv

dotenv 支持 shell 和 POSIX 兼容的 .env 语法规范
https://github.com/ko1nksm/shdotenv

eval "$(shdotenv)"

用法

Usage: shdotenv [OPTION]... [--] [COMMAND [ARG]...]

  -d, --dialect DIALECT  Specify the .env dialect [default: posix]
                           (posix, ruby, node, python, php, go, rust, docker)
  -s, --shell SHELL      Output in the specified shell format [default: posix]
                           (posix, fish)
  -e, --env ENV_PATH     Location of the .env file [default: .env]
                           Multiple -e options are allowed
  -o, --overload         Overload predefined environment variables
  -n, --noexport         Do not export keys without export prefix
  -g, --grep PATTERN     Output only those that match the regexp pattern
  -k, --keyonly          Output only variable names
  -q, --quiet            Suppress all output
  -v, --version          Show the version and exit
  -h, --help             Show this message and exit

要求

shdotenv 是一个带有嵌入式 awk 脚本的单文件 shell 脚本。

  • POSIX shell(dash、bash、ksh、zsh 等)
  • awk(gawk、nawk、mawk、busybox awk)
于 2021-05-02T14:56:12.703 回答
4

我对早期建议的解决方案有疑问:

  • @anubhava 的解决方案使编写 bash 友好的配置文件非常烦人,而且 - 您可能不想总是导出您的配置。
  • @Silas Paul 解决方案在您的变量中包含空格或其他字符在引用值中运行良好但$()会造成混乱时会中断。

这是我的解决方案,它仍然是非常糟糕的 IMO - 并没有解决 Silas 解决的“仅导出给一个孩子”问题(尽管您可能可以在子 shell 中运行它以限制范围):

source .conf-file
export $(cut -d= -f1 < .conf-file)
于 2015-01-28T09:53:19.207 回答
4

我的要求是:

  • 没有前缀的简单 .env 文件export(为了与 dotenv 兼容)
  • 引号中的支持值:TEXT="alpha bravo charlie"
  • 支持以 # 和空行为前缀的注释
  • mac/BSD 和 linux/GNU 通用

从上面的答案编译的完整工作版本:

  set -o allexport
  eval $(grep -v '^#' .env | sed 's/^/export /')
  set +o allexport
于 2019-04-18T10:13:51.723 回答
4

我用这个:

source <(cat .env \
  | sed -E '/^\s*#.*/d' \
  | tr '\n' '\000' \
  | sed -z -E 's/^([^=]+)=(.*)/\1\x0\2/g' \
  | xargs -0 -n2 bash -c 'printf "export %s=%q;\n" "${@}"' /dev/null)

首先删除评论:

sed -E '/^\s*#.*/d'

然后转换为空分隔符而不是换行符:

tr '\n' '\000'

然后用null替换equal:

sed -z -E 's/^([^=]+)=(.*)/\1\x0\2/g'

然后将对打印到有效的引用 bash 导出(使用 bash printf for %q):

xargs -0 -n2 bash -c 'printf "export %s=%q;\n" "${@}"' /dev/null

然后最终采购所有这些。

它应该适用于几乎所有具有所有特殊字符的情况。

于 2020-09-15T13:18:10.757 回答
4

我的版本:

我打印文件,删除注释行,空行,并从“=”符号中拆分键/值。然后我只应用导出命令。

此解决方案的优点是文件可以在值中包含特殊字符,如管道、html 标记等,并且值不必像真正的属性文件那样用引号括起来。

# Single line version
cat myenvfile.properties | grep -v '^#' | grep '=' | while read line; do IFS=\= read k v <<< $line; export $k="$v"; done

# Mutliline version:
cat myenvfile.properties | grep -v '^#' | grep '=' | while read line; do 
  IFS=\= read k v <<< $line
  export $k="$v"
done

于 2021-10-22T07:43:35.413 回答
3

首先,创建一个环境文件,该文件将包含以下环境的所有键值对,并在我的情况下将其命名为您喜欢的任何名称env_var.env

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

然后创建一个脚本,将导出python环境的所有环境变量,如下所示,并将其命名为export_env.sh

#!/usr/bin/env bash

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

set -o allexport
source $ENV_FILE
set +o allexport

$CMD

该脚本将第一个参数作为环境文件,然后导出该文件中的所有环境变量,然后运行该命令。

用法:

./export_env.sh env_var.env python app.py
于 2019-05-20T07:03:21.333 回答
3

这是我对此的看法。我有以下要求:

  • 忽略注释行
  • 允许值中有空格
  • 允许空行
  • 能够在默认为 .env 时传递自定义 env 文件
  • 允许导出以及内联运行命令
  • 如果 env 文件不存在则退出
source_env() {
  [ "$#" -eq 1 ] && env="$1" || env=".env"
  [ -f "$env" ] || { echo "Env file $env doesn't exist"; return 1; }
  eval $(grep -Ev '^#|^$' "$env" | sed -e 's/=\(.*\)/="\1/g' -e 's/$/"/g' -e 's/^/export /')
}

将函数保存到 .bash_profile 或等效文件后的用法:

source_env                # load default .env file
source_env .env.dev       # load custom .env file
(source_env && COMMAND)   # run command without saving vars to environment

受到哈维尔和其他一些评论的启发。

于 2020-08-10T12:48:06.847 回答
3

修改自@Dan Kowalczyk

我把这个放进去~/.bashrc

set -a
. ./.env >/dev/null 2>&1
set +a

与 Oh-my-Zsh 的 dotenv 插件很好地交叉兼容。(有 Oh-my-bash,但没有 dotenv 插件。)

于 2020-08-21T02:18:11.593 回答
2

值中的空格

这里有很多很好的答案,但我发现它们都缺乏对值中空白的支持:

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

我找到了 2 个解决方案,这些解决方案适用于此类值,并支持空行和注释。

一个基于 sed 和 @javier-buzzi 的答案

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

还有一个基于@john1024答案的循环中的读取行

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

这里的关键是使用declare -x双引号并将行放在双引号中。我不知道为什么,但是当你将循环代码重新格式化为多行时,它就不起作用了——我不是 bash 程序员,我只是狼吞虎咽,对我来说仍然很神奇:)

于 2018-04-05T14:20:50.883 回答
2

我如何保存变量:

printenv | sed 's/\([a-zA-Z0-9_]*\)=\(.*\)/export \1="\2"/' > myvariables.sh

我如何加载它们

source myvariables.sh
于 2020-12-03T10:48:08.053 回答
1

--env-file当我尝试在 shell 中 重用 Docker 时,我遇到了这个线程。它们的格式与 bash 不兼容,但很简单:name=value,没有引用,没有替换。他们也忽略空行和#注释。

我不能完全让它与 posix 兼容,但这里有一个应该在类似 bash 的 shell 中工作(在 OSX 10.12.5 上的 zsh 和 Ubuntu 14.04 上的 bash 中测试):

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

在上面链接的文档的示例中,它不会处理三种情况:

  • bash: export: `123qwe=bar': not a valid identifier
  • bash: export: `org.spring.config=something': not a valid identifier
  • 并且它不会处理直通语法(裸露的FOO
于 2017-06-23T20:55:25.290 回答
1

尝试这样的事情

for line in `cat your_env_file`; do if [[ $line != \#* ]];then export $line; fi;done
于 2019-11-26T12:55:51.287 回答
1

我的 .env 文件如下所示:

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

使用@henke的方式,导出的值最终包含引号"

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

但我希望导出的值仅包含:

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

要修复它,我编辑命令以删除引号:

export $(grep -v '^#' dev.env | tr --delete '"' | xargs -d '\n')
于 2019-12-19T13:44:47.917 回答
1
sh -ac '. conf-file; yourcommand'

-a开关导出所有变量,以便程序可以使用它们。

与较长的版本不同,set -a; . conf-file; set +a; yourcommand 使用sh确保导出的值不会永久污染当前环境。它仅为在子外壳中运行的程序提供和导出变量。

于 2021-12-24T08:52:06.307 回答
1

export是答案

互动练习

由于交互式的,您可以尝试内联!

$ mkdir conf && printf 'MINIENTREGA_%s="%s"\n' FECHALIMITE 2011-03-31 FICHEROS \
    "informe.txt programa.c" DESTINO ./destino/entrega-prac1 >conf/prac1 

$ set -- prac1
$ while read -r line; do export $line; done <"conf/$1"
bash: export: `programa.c"': not a valid identifier
$ while read -r line; do LANG=C export "$line"; done <"conf/$1"
$ echo "$MINIENTREGA_FICHEROS"
"informe.txt programa.c"

注意双引号!

source别名.

$ set -- prac1
$ . "conf/$1"
$ echo "$MINIENTREGA_FICHEROS"
informe.txt programa.c

好的,那么现在是什么export

export命令告诉 shell将shell 变量导出环境......所以你必须在使用它们之前导出脚本变量是任何子进程(如, ,甚至是另一个脚本。rubypythonperlshell

清理以前的操作以进行进一步的演示

$ declare +x MINIENTREGA_FECHALIMITE MINIENTREGA_FICHEROS MINIENTREGA_DESTINO
$ unset MINIENTREGA_FECHALIMITE MINIENTREGA_FICHEROS MINIENTREGA_DESTINO

因此,从交互式 shell 中,最简单的尝试方法是运行另一个

$ set -- prac1
$ . "conf/$1"
$ bash -c 'declare -p MINIENTREGA_FICHEROS'
bash: line 1: declare: MINIENTREGA_FICHEROS: not found

$ export MINIENTREGA_FECHALIMITE MINIENTREGA_FICHEROS MINIENTREGA_DESTINO
$ bash -c 'declare -p MINIENTREGA_FICHEROS'
declare -x MINIENTREGA_FICHEROS="informe.txt programa.c"

用于导出变量的示例 包装器

最小的包装器,没有安全问题(在获取其他用户可编辑的脚本时要小心!!)。

#!/bin/sh

while IFS== read -r varname _;do
    case $varname in
         *[!A-Za-z0-9_]* | '' ) ;;
         * ) export $varname ;;
    esac
done <conf/$1
. conf/$1

busybox sh -c 'set | grep MINIENTREGA'

使用prac1as 参数运行,应产生:

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

很好

  • 采购配置文件与声明变量相同。

  • 导出变量是指示 shell 在全局环境中为任何子进程共享他的变量。

这两个操作可以以任何顺序无差别地完成。唯一的要求是在您尝试运行任何子进程之前完成这两个操作。

您甚至可以通过配置文件中导出来同时执行这两项操作,例如:

export MINIENTREGA_FECHALIMITE="2011-03-31"
export MINIENTREGA_FICHEROS="informe.txt programa.c"
export MINIENTREGA_DESTINO="./destino/entrega-prac1"
于 2022-01-08T15:11:56.113 回答
0

如果您因为其中一个变量包含包含空格的值而出现错误,您可以尝试重置 bash IFS(内部字段分隔符)以\n让 bash 将cat .env结果解释为env可执行文件的参数列表。

例子:

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

也可以看看:

于 2015-12-20T20:23:41.773 回答
0

这个处理 RHS 上的空格,并跳过“奇怪”的变量,例如 bash 模块定义(其中包含“()”):

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
于 2020-04-18T17:31:56.583 回答
0

如果您打算将其作为脚本的最后一个命令,则可以使用解释器exec来获得额外的选项。execlineb这就是脚本最后一行的样子:

#!/bin/sh
...
exec envfile -I /etc/default/bla envfile /etc/default/bla-bla my_cmd

envfile ...execline套件中的命令,它们依赖于“链式加载”。顺便说一句,一旦你进入这个兔子洞,你可能会发现你不再需要 shell(......并重新考虑你的其他生活选择:-) 通过使用execlineb解释器而不是完全使用 shell,它对于以最小开销启动服务非常有用, IE:

#!/bin/execlineb
...
envfile -I /etc/default/bla
envfile /etc/default/bla-bla
my_cmd
于 2021-04-26T14:33:03.390 回答
0

我对此的贡献是扩展了来自@ user4040650 的答案,以允许在 git repo 中轻松使用。它将尝试从当前目录中获取 .env 文件,或者如果该文件不存在,则从您所在的 git 存储库中获取 .env 。如果您已 cd 进入子目录然后不要'不必来源 ../../.env 或诸如此类。

我把它放在我的 .bashrc 中,所以我只需要setenv在需要的地方调用

setenv() {
  local env_path
  if { [ -f .env ] && env_path='.env'; } || { env_path=$(git  rev-parse --show-toplevel 2>/dev/null)/.env && [ -f "$env_path" ]; }; then
    echo "sourcing $env_path"
    set -o allexport
    source "$env_path"
    set +o allexport
  else
    echo "No env file found"
  fi
}
于 2021-07-21T06:18:58.143 回答
0

符合 POSIX 的解决方案(不依赖 bash)

正如其他人所指出的,在此处使用 for/while 循环的问题在于,变量在 shell 及其子 shell 之间不共享。然而,我们可以做的是使用 args/stdin/stdout 在 shell 之间传递文本。

当我们获取脚本时,在子 shell 中设置环境变量不会有帮助

变量不会传播回来 - 但我们知道我们可以发回文本。这个文本也可以是代码,我们可以在当前的 shell 中使用eval.

如果我们改为生成设置所有环境变量的代码,然后评估结果会怎样?

create_exports_script() {
    echo "$1" | while read line; do
        echo "export $line"
    done
}

file_contents=$(cat "./conf/myconf.env")
eval $(create_exports_script "$file_contents")

bash 中的这种函数式元编程可以非常灵活。您还可以通过这种方式生成bash/sh 以外的其他语言

于 2021-09-01T23:19:35.497 回答
-1

对于那些使用 ruby​​ 的人,我制作了一个名为dotenv_export.

用法

dotenv_export是一个小型实用程序命令,它读取.env文件并将其转换为使用ruby​​ 实现export的语句。dotenv

# first install `dotenv_export`
gem install dotenv_export

然后,在您的.bash_profile或您要加载环境变量的任何 shell 环境中,执行以下命令:

eval "$(dotenv-export /path/to/.env)"
于 2020-09-14T02:39:55.867 回答