简体   繁体   English

导出本地开发和heroku部署的环境变量

[英]Exporting environment variables for local development and heroku deployment

I would like to setup some files for development, staging and production with environment variables, for example: 我想用环境变量设置一些用于开发,登台和生产的文件,例如:

application_root/development.env

KEY1=value1
KEY2=value2

There would be similar files staging.env and production.env . 会有类似的文件staging.envproduction.env

I am looking for a couple different bash scripts which would allow the loading of all these variables in either development or staging/production. 我正在寻找几个不同的bash脚本,这些脚本允许在开发或暂存/生产中加载所有这些变量。

In local development I want to effectively run export KEY1=value1 for each line in the file. 在本地开发中,我想有效地为文件中的每一行运行export KEY1=value1

For staging/production I will be deploying to Heroku and would like to effectively run heroku config:set -a herokuappname KEY1=value1 for each line in the staging or production.env files. 对于登台/制作,我将部署到Heroku,并希望有效地运行heroku config:set -a herokuappname KEY1=value1stagingproduction.env文件中的每一行heroku config:set -a herokuappname KEY1=value1

I know there are some gems designed for doing this but it seems like this might be pretty simple. 我知道有一些宝石设计用于这样做,但似乎这可能非常简单。 I also like the flexibility of having the .env files as simple lists of keys and values and not specifically being tied to any language/framework. 我也喜欢将.env文件作为简单的键和值列表的灵活性,而不是特别绑定到任何语言/框架。 If I would have to change something about the way these variables need to be loaded it would be a matter of changing the script but not the .env files. 如果我不得不改变一些关于这些变量需要加载的方式,那就是更改脚本而不是.env文件。

In the simplest form, you can load the key-value pairs into a bash array as follows: 在最简单的形式中,您可以将键值对加载到bash数组中,如下所示:

IFS=$'\n' read -d '' -ra nameValuePairs < ./development.env

In Bash v4+, it's even simpler: 在Bash v4 +中,它甚至更简单:

readarray -t nameValuePairs < ./development.env

You can then pass the resulting "${nameValuePairs[@]}" array to commands such as export or heroku config:set ... ; 然后,您可以将生成的"${nameValuePairs[@]}"数组传递给诸如exportheroku config:set ...命令heroku config:set ... ; eg: 例如:

export "${nameValuePairs[@]}"

Note, however, that the above only works as intended if the input *.env file meets all of the following criteria: 但请注意,如果输入*.env文件满足以下所有条件,则上述操作仅按预期工作:

  • the keys are syntactically valid shell variable names and the lines have the form <key>=<value> , with no whitespace around = 键是语法上有效的shell变量名,行的格式为<key>=<value> ,周围没有空格=
  • the lines contain no quoting and no leading or trailing whitespace 这些行不包含引号,也没有前导或尾随空格
  • there are no empty/blank lines or comment lines in the file. 文件中没有空/空行或注释行。
  • the values are confined to a single line each. 每个值都限制在一行。

A different approach is needed with files that do not adhere to this strict format; 对于不符合此严格格式的文件,需要采用不同的方法; for instance, this related question deals with files that may contain quoted values. 例如, 此相关问题处理可能包含引用值的文件。


Below is the source code for a bash script named load_env (the .sh suffix is generally not necessary and ambiguous): 下面是名为load_envbash脚本的源代码( .sh后缀通常不是必需且不明确的):

  • You'd invoke it with the *.env file of interest, and it would perform the appropriate action (running heroku config:set … or export ) based on the filename . 你会与调用它*.env感兴趣的文件,它会执行相应的操作(运行heroku config:set …export基础上的文件名 )。

  • However, as stated, you must source the script (using source or its effective bash alias, . ) in order to create environment variables ( export ) visible to the current shell. 然而,按照规定,必须执行此脚本(使用source或者其有效bash别名.为了营造环境变量() export ),以当前 shell可见。
    To prevent obscure failures, the script complains if you pass a development.env file and have invoked the script without sourcing. 为了防止模糊的故障,如果您传递了development.env文件并且在没有采购的情况下调用了脚本,脚本会抱怨。

Examples: 例子:

./load_env ./staging.dev  
. ./load_env ./development.dev   # !! Note the need to source

load_env source code load_env源代码

#!/usr/bin/env bash

# Helper function that keeps its aux. variables localized.
# Note that the function itself remains defined after sourced invocation, however.
configOrExport() {

  local envFile=$1 doConfig=0 doExport=0 appName

  case "$(basename "$envFile" '.env')" in
    staging)
      doConfig=1
      # Set the desired app name here.
      appName=stagingapp
      ;;
    production)
      doConfig=1
      # Set the desired app name here.
      appName=productionapp
      ;;
    development)
      doExport=1
      ;;
    *)
      echo "ERROR: Invalid or missing *.env file name: $(basename "$envFile" '.env')" >&2; exit 2
  esac

  # Make sure the file exists and is readable.
  [[ -r "$envFile" ]] || { echo "ERROR: *.env file not found or not readable: $envFile" >&2; exit 2; }

  # If variables must be exported, make sure the script is being sourced.
  [[ $doExport -eq 1 && $0 == "$BASH_SOURCE" ]] && { echo "ERROR: To define environment variables, you must *source* this script." >&2; exit 2; }

  # Read all key-value pairs from the *.env file into an array.
  # Note: This assumes that:
  #        - the keys are syntactically valid shell variable names
  #        - the lines contain no quoting and no leading or trailing whitespace
  #        - there are no empty/blank lines or comment lines in the file.
  IFS=$'\n' read -d '' -ra nameValuePairs < "$envFile"

  # Run configuration command.
  (( doConfig )) && { heroku config:set -a "$appName" "${nameValuePairs[@]}" || exit; }

  # Export variables (define as environment variables).
  (( doExport )) && { export "${nameValuePairs[@]}" || exit; }

}

# Invoke the helper function.
configOrExport "$@"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM