bash - 使用 bash 读取 .env (带空格的变量)

标签 bash docker environment-variables

我正在使用nodedock。

它有一个 start.sh 脚本来启动你的 docker

#!/usr/bin/env bash

set -e
cd "$( dirname "${BASH_SOURCE[0]}" )"

if [ ! -f .env ]; then
  echo "Having .env is required. Maybe you forgot to copy env-example?"
  exit 1
fi

while read -r line; do
  VARNAME=$(echo ${line} | awk '{sub(/\=.*/,x)}1')

  if [[ -z ${!VARNAME} ]]; then
    declare -x ${line}
  fi
done < <(egrep -v "(^#|^\s|^$)" .env)

docker-compose up -d ${NODEDOCK_SERVICES}
docker-compose logs -t -f ${NODEDOCK_LOG_AFTER_START}

NODEDOCK_SERVICES = nginx 节点工作区 mongo

如果发现如果你需要一个带空格的变量,你必须用双引号编写你的环境变量“nginx节点工作区mongo”

问题是这个“req expression”VARNAME=$(echo ${line} | awk '{sub(/\=.*/,x)}1') 不使用双引号。

有什么解决办法吗?

最佳答案

问题不在于您的 awk 表达式,而是当您调用 declare 内置函数时。声明时使用正确的引号。

declare -x "$str"

因为如果没有引号,您的作业将如下所示

declare -x NODEDOCK_SERVICES=nginx node workspace mongo

它按空格分割,结果字符串的第一个单词被分配给NODEDOCK_SERVICES。但使用正确的引号,赋值将保持完整,保留结果字符串中的空格。

也就是说,您的整个循环可以通过使 read 循环解析以 = 作为分隔符的行来修改,这样您就可以轻松解析键/值对。目前不清楚您文件中的作业是否采用下面的形式 1 或 2

NODEDOCK_SERVICES = nginx node workspace mongo
NODEDOCK_SERVICES=nginx node workspace mongo

以下逻辑适用于这两种情况

shopt -s extglob
while IFS== read -r key value; do 
    key=${key%%+([[:space:]])}  
    value=${value##+([[:space:]])} 
    if [[ -z ${!key} ]]; then
        declare -x "$key=$value"
    fi
done < <(egrep -v "(^#|^\s|^$)" .env)

作为一个好的做法,请始终在 bash 中引用变量,除非您有充分的理由不这样做。小写的用户定义变量可以帮助您将它们与 shell 本身维护的环境变量区分开来。

关于bash - 使用 bash 读取 .env (带空格的变量),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54759987/

相关文章:

linux - 在 bash 脚本中循环和复制

c - 脚本 bash 写入 fifo 并从中读取 c 程序

bash - Gitlab:使用 grep 的管道命令不起作用?

php - docker php7.2-fpm无法安装imap模块

amazon-web-services - 云信息 : How to pass a string through cloudformation script into UserData?

linux - 将/etc/yum.repos.d/* 复制到所有计算机上的同一目录,而无需重复输入 root 密码

docker-compose 运行任何命令都会出错

Docker swarm加入linux容器错误-远程CA与指纹不匹配

node.js - ENV 变量未正确添加到容器环境中

python - PYTHONPATH 和 PYTHON_LIBRARY_PATH 是什么?