我正在使用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')
不适用于双引号。
有解决方案吗
问题不在于你的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本身维护的环境变量区分开来。
如果您想从.env文件格式中读取特定变量(可能不完全是您的问题,但它可能对其他人有帮助,因为您的标题可能会产生误导):
read_var() {
VAR=$(grep "^$1=" $2 | xargs)
IFS="=" read -ra VAR <<< "$VAR"
IFS=" "
echo ${VAR[1]}
}