我创建了一个自定义docker容器,该容器调用了启动脚本。该脚本需要一些数据,这些数据存储在我的.env
文件中。
所有文件所需的所有变量都存储在.env
中,这就是我要保留的位置。我可以以这种方式传递变量而不会出错...只是数组我无法正确传递。
.env
:
FOO=1 # blah
BAR='bar' # this does blah
MYARRAY=(
hello # blah
world # blah
)
docker-compose.yml
:
mycontainer:
env_file: .env
build:
context: .
args: # pass variables into dockerfile
FOO: ${FOO}
MYARRAY: ${MYARRAY}
Dockerfile
:
FROM some_app
ARG FOO
ARG MYARRAY
ENV \
FOO=$FOO \
MYARRAY=$MYARRAY # pass variables into script
CMD [ "myscript.sh" ]
myscript.sh
:
#!/bin/bash
set -Eeuo pipefail
echo "$FOO" # works
for i in "${MYARRAY[@]}"; do echo "$i"; done # <---- problem is here
数组在脚本中并未完整到达-它以"("
的形式到达。这是因为它是从ini到yaml到dockerfile语法到bash的“翻译”。
如何对.env
中的内容进行转义/格式化,以使其正确到达bash脚本中?
答案 0 :(得分:2)
使用declare -p
输出并将数组作为纯文本传输。
MYARRAY=(hello world)
稍后在脚本中
declare -a MYARRAY="$MYARRAY"
printf "%s\n" "${MYARRAY[@]}"
bash数组是bash的扩展,在其他任何地方均不支持。环境变量只能包含文本和值。通过使用declare -p
(甚至使用declare -f
正确地转义和提取的文本)传递更复杂的内容。对于困难的情况,您可以借助printf "%q"
来准备(甚至从某些脚本自动生成)数组:
hardarray=('!@#\''\' "space space")
printf "%q" "$(declare -p hardarray | cut -d= -f2-)" # put the output in .env file
# then add in your .env file:
hardarray=\(\[0\]=\"\!@#\\\\\\\\\"\ \[1\]=\"space\ space\"\)
# then later read the array in your script:
declare -a hardarray="$hardarray"
我相信在docker-compose中通过env_file传递多行字符串是不可能的。我只建议从Shell脚本生成它(但是可悲的是,这为构建过程增加了另一个阶段)。