用bash读取.env(带空格的变种)

问题描述 投票:2回答:2

我正在使用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 node workspace mongo

如果发现如果你需要一个带空格的变量你必须用双引号"nginx node workspace mongo"写你的env变量

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

有解决方案吗

bash docker environment-variables
2个回答
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本身维护的环境变量区分开来。


1
投票

如果您想从.env文件格式中读取特定变量(可能不完全是您的问题,但它可能对其他人有帮助,因为您的标题可能会产生误导):

read_var() {
    VAR=$(grep "^$1=" $2 | xargs)
    IFS="=" read -ra VAR <<< "$VAR"
    IFS=" "
    echo ${VAR[1]}
}
© www.soinside.com 2019 - 2024. All rights reserved.