将数组从.env传递到docker-compose.yml到Dockerfile到bash脚本

时间:2019-12-03 12:43:21

标签: linux bash docker docker-compose yaml

我创建了一个自定义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脚本中?

1 个答案:

答案 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脚本生成它(但是可悲的是,这为构建过程增加了另一个阶段)。