hug*_*994 425 variables bash environment-variables
TL; DR:如何将一组键/值对从文本文件导出到shell环境中?
为了记录,下面是问题的原始版本,带有示例.
我正在用bash编写一个脚本,用于解析某个文件夹中包含3个变量的文件,这是其中之一:
MINIENTREGA_FECHALIMITE="2011-03-31"
MINIENTREGA_FICHEROS="informe.txt programa.c"
MINIENTREGA_DESTINO="./destino/entrega-prac1"
Run Code Online (Sandbox Code Playgroud)
该文件存储在./conf/prac1中
我的脚本minientrega.sh然后使用以下代码解析文件:
cat ./conf/$1 | while read line; do
export $line
done
Run Code Online (Sandbox Code Playgroud)
但是当我minientrega.sh prac1在命令行中执行时,它不会设置环境变量
我也试过使用,source ./conf/$1但同样的问题仍然适用
也许有其他方法可以做到这一点,我只需要使用我传递的文件的环境变量作为我的脚本的参数.
Sil*_*aul 765
这可能会有所帮助:
export $(cat .env | xargs) && rails c
Run Code Online (Sandbox Code Playgroud)
我使用它的原因是我想.env在rails控制台中测试内容.
gabrielf提出了一个很好的方法来保持变量本地化.这解决了从项目到项目的潜在问题.
env $(cat .env | xargs) rails
Run Code Online (Sandbox Code Playgroud)
我已经测试了这个 bash 3.2.51(1)-release
更新:
要忽略以开头的行#,请使用此(感谢Pete的评论):
export $(grep -v '^#' .env | xargs)
Run Code Online (Sandbox Code Playgroud)
如果你想要unset文件中定义的所有变量,请使用:
unset $(grep -v '^#' .env | sed -E 's/(.*)=.*/\1/' | xargs)
Run Code Online (Sandbox Code Playgroud)
更新:
要使用空格处理值,请使用:
export $(grep -v '^#' .env | xargs -d '\n')
Run Code Online (Sandbox Code Playgroud)
在GNU系统上或:
export $(grep -v '^#' .env | xargs -0)
Run Code Online (Sandbox Code Playgroud)
在BSD系统上.
小智 332
-o allexport允许导出所有后续变量定义.+o allexport禁用此功能.
set -o allexport
source conf-file
set +o allexport
Run Code Online (Sandbox Code Playgroud)
anu*_*ava 166
你的方法的问题是export在while循环中一个子壳发生,这些变量不会在当前的shell(while循环的父shell)可用.
export在文件本身中添加命令:
export MINIENTREGA_FECHALIMITE="2011-03-31"
export MINIENTREGA_FICHEROS="informe.txt programa.c"
export MINIENTREGA_DESTINO="./destino/entrega-prac1"
Run Code Online (Sandbox Code Playgroud)
然后你需要使用以下命令在当前shell中的文件中获取:
. ./conf/prac1
Run Code Online (Sandbox Code Playgroud)
要么
source ./conf/prac1
Run Code Online (Sandbox Code Playgroud)
Dan*_*zyk 105
set -a
. ./env.txt
set +a
Run Code Online (Sandbox Code Playgroud)
如果env.txt是这样的话:
VAR1=1
VAR2=2
VAR3=3
...
Run Code Online (Sandbox Code Playgroud)
Hua*_*uan 60
我发现最有效的方法是:
export $(xargs < .env)
Run Code Online (Sandbox Code Playgroud)
当我们有这样的.env文件时:
key=val
foo=bar
Run Code Online (Sandbox Code Playgroud)
运行xargs < .env会得到key=val foo=bar
所以我们会得到一个export key=val foo=bar,这正是我们所需要的!
gsf*_*gsf 28
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
}
Run Code Online (Sandbox Code Playgroud)
sel*_*van 25
eval $(cat .env | sed 's/^/export /')
Run Code Online (Sandbox Code Playgroud)
tut*_*uju 20
这是另一个sed解决方案,它不运行eval或需要ruby:
source <(sed -E -n 's/[^#]+/export &/ p' ~/.env)
Run Code Online (Sandbox Code Playgroud)
这会添加导出,在注释开头的行上保留注释.
A=1
#B=2
Run Code Online (Sandbox Code Playgroud)
$ sed -E -n 's/[^#]+/export &/ p' ~/.env
export A=1
#export B=2
Run Code Online (Sandbox Code Playgroud)
我发现这在构建用于在systemd单元文件中EnvironmentFile加载的文件时特别有用.
Nag*_*gev 17
我赞成了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"
Run Code Online (Sandbox Code Playgroud)
以下是从设置文档中提取的:
这个内置是如此复杂,它应该有自己的部分.set允许您更改shell选项的值并设置位置参数,或显示shell变量的名称和值.
set [--abefhkmnptuvxBCEHPT] [-o option-name] [argument ...] set [+ abefhkmnptuvxBCEHPT] [+ o option-name] [argument ...]
如果未提供任何选项或参数,则set将显示所有shell变量和函数的名称和值,并根据当前区域设置进行排序,格式可以重复用作设置或重置当前设置变量的输入.只读变量无法重置.在POSIX模式下,仅列出shell变量.
提供选项时,它们会设置或取消设置shell属性.选项(如果指定)具有以下含义:
-a创建或修改的每个变量或函数都具有export属性,并标记为导出到后续命令的环境.
这也是:
使用"+"而不是" - "会导致关闭这些选项.这些选项也可以在调用shell时使用.当前的选项集可以在$ - 中找到.
Jul*_*lle 15
不完全确定为什么,或者我错过了什么,但是在运行了大部分答案并失败之后。我意识到这个 .env 文件:
MY_VAR="hello there!"
MY_OTHER_VAR=123
Run Code Online (Sandbox Code Playgroud)
我可以简单地这样做:
MY_VAR="hello there!"
MY_OTHER_VAR=123
Run Code Online (Sandbox Code Playgroud)
输出: Hello there!
似乎在 Ubuntu linux 中工作得很好。
Koi*_*ima 14
dotenv 支持 shell 和符合 POSIX 的 .env 语法规范
https://github.com/ko1nksm/shdotenv
eval "$(shdotenv)"
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
shdotenv 是一个嵌入 awk 脚本的单文件 shell 脚本。
gle*_*len 13
这是我的变体:
with_env() {
(set -a && . ./.env && "$@")
}
Run Code Online (Sandbox Code Playgroud)
与之前的解决方案相比:
.env的值不会暴露给调用者)set选项set -a.而不是source避免bashism.env加载失败,则不会调用命令with_env rails console
Run Code Online (Sandbox Code Playgroud)
jwf*_*arn 12
SAVE=$(set +o) && set -o allexport && . .env; eval "$SAVE"
这将保存/恢复您的原始选项,无论它们是什么.
使用set -o allexport具有正确跳过注释而无需正则表达式的优点.
set +o它本身以bash以后可以执行的格式输出所有当前选项.同样方便:set -o单独输出所有当前选项的人性化格式.
Til*_*gel 12
很抱歉添加另一个答案,但因为它很简单并且在很多情况下都有效,请尝试:
export $(< ~/my/.env)
Run Code Online (Sandbox Code Playgroud)
kol*_*pto 10
问题source在于它要求文件具有正确的 bash 语法,而一些特殊字符会破坏它:=, ", ', <, >, 和其他。所以在某些情况下你可以
source development.env
Run Code Online (Sandbox Code Playgroud)
它会起作用。
但是,此版本可承受值中的每个特殊字符:
source development.env
Run Code Online (Sandbox Code Playgroud)
解释:
-a 意味着每个 bash 变量都将成为环境变量/^#/d删除注释(以 开头的字符串#)/^\s*$/d 删除空字符串,包括空格"s/'/'\\\''/g"用 替换每个单引号'\'',这是 bash 中生成引号的技巧序列:)"s/=\(.*\)/='\1'/g"将每个a=b转换为a='b'因此,您可以使用特殊字符:)
要调试此代码,请替换source为cat,您将看到此命令生成的内容。
更简单:
export到所有行eval 整个东西eval $(cat .env | sed -e /^$/d -e /^#/d -e 's/^/export /')
另一种选择(你不必跑eval(感谢@Jaydeep)):
export $(cat .env | sed -e /^$/d -e /^#/d | xargs)
Run Code Online (Sandbox Code Playgroud)
最后,如果您想让自己的生活变得非常轻松,请将其添加到您的~/.bash_profile:
function source_envfile() { export $(cat $1 | sed -e /^$/d -e /^#/d | xargs); }
(请source ~/.bash_profile确保您重新安装了您的BASH设置!!! 或者......只需创建一个新的选项卡/窗口并解决问题)您可以这样称呼它:source_envfile .env
我找到的最短方法:
您的.env档案:
VARIABLE_NAME="A_VALUE"
Run Code Online (Sandbox Code Playgroud)
然后就
. ./.env && echo ${VARIABLE_NAME}
Run Code Online (Sandbox Code Playgroud)
奖励:因为它是短线,所以在package.json文件中非常有用
"scripts": {
"echo:variable": ". ./.env && echo ${VARIABLE_NAME}"
}
Run Code Online (Sandbox Code Playgroud)
我.env在 Mac 上使用 docker-compose 和files,并希望将其.env导入我的 bash shell(用于测试),这里的“最佳”答案是在以下变量上绊倒:
.env
NODE_ARGS=--expose-gc --max_old_space_size=2048
Run Code Online (Sandbox Code Playgroud)
所以我最终使用eval, 并将我的 env var defs 用单引号括起来。
eval $(grep -v -e '^#' .env | xargs -I {} echo export \'{}\')
Run Code Online (Sandbox Code Playgroud)
bash 版本
$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.
Run Code Online (Sandbox Code Playgroud)
t=$(mktemp) && export -p > "$t" && set -a && . ./.env && set +a && . "$t" && rm "$t" && unset t
Run Code Online (Sandbox Code Playgroud)
这个怎么运作
.env文件。所有变量都将导出到当前环境中。declare -x VAR="val"将每个变量导出到环境中。特征
.env 可以评论.env 可以有空行.env不需要像其他答案(set -a和set +a)中那样的特殊页眉或页脚.env不需要export对每个值都有如果env支持该-S选项,则可以使用换行符或转义字符,如\n或\t(请参阅env):
env -S "$(cat .env)" command
Run Code Online (Sandbox Code Playgroud)
.env 文件示例:
KEY="value with space\nnewline\ttab\tand
multiple
lines"
Run Code Online (Sandbox Code Playgroud)
测试:
KEY="value with space\nnewline\ttab\tand
multiple
lines"
Run Code Online (Sandbox Code Playgroud)
我的要求是:
export(为了与 dotenv 兼容)根据上面的答案编译的完整工作版本:
set -o allexport
eval $(grep -v '^#' .env | sed 's/^/export /')
set +o allexport
Run Code Online (Sandbox Code Playgroud)
您可以使用原始脚本来设置变量,但需要按以下方式调用它(使用独立点):
. ./minientrega.sh
Run Code Online (Sandbox Code Playgroud)
方法也可能存在问题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
Run Code Online (Sandbox Code Playgroud)
我对之前建议的解决方案有疑问:
$()会造成混乱。这是我的解决方案,在我看来,它仍然非常糟糕 - 并且不能解决 Silas 解决的“仅导出到一个孩子”的问题(尽管您可以在子 shell 中运行它以限制范围):
source .conf-file
export $(cut -d= -f1 < .conf-file)
Run Code Online (Sandbox Code Playgroud)
在其他答案的基础上,这里是一种只导出文件中一行的子集的方法,包括带有空格的值,如PREFIX_ONE="a word":
set -a
. <(grep '^[ ]*PREFIX_' conf-file)
set +a
Run Code Online (Sandbox Code Playgroud)
我的.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
Run Code Online (Sandbox Code Playgroud)
调用:
source .env; echo $USER; echo $PASS
Run Code Online (Sandbox Code Playgroud)
参考https://unix.stackexchange.com/questions/79068/how-to-export-variables-that-are-set-all-at-once
这是我对此的看法。我有以下要求:
source_env() {
env=${1:-.env}
[ ! -f "${env}" ] && { echo "Env file ${env} doesn't exist"; return 1; }
eval $(sed -e '/^\s*$/d' -e '/^\s*#/d' -e 's/=/="/' -e 's/$/"/' -e 's/^/export /' "${env}")
}
Run Code Online (Sandbox Code Playgroud)
将函数保存到 .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
Run Code Online (Sandbox Code Playgroud)
受到哈维尔和其他一些评论的启发。
小智 5
我的版本:
我打印文件,删除注释行、空行,然后将键/值从“=”符号中拆分出来。然后我只需应用导出命令。
此解决方案的优点是文件可以在值中包含特殊字符,例如管道、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
Run Code Online (Sandbox Code Playgroud)