文本文件中保留空白的Shell变量扩展(例如,Rancher中docker-compose.yml的用法)

文本文件中保留空白的Shell变量扩展(例如,Rancher中docker-compose.yml的用法),shell,docker-compose,yaml,rancher,variable-expansion,Shell,Docker Compose,Yaml,Rancher,Variable Expansion,我希望使用YAML文件中的默认值执行shell扩展,保留其结构和前导空格,以保持其可用性 例如: version: 2 services: postgres: image: ${POSTGRESQL_IMAGE:-my-private-registry/postgres}:${POSTGRESQL_BUILD:-9.6}" labels: io.rancher.scheduler.affinity:host_label: myproj

我希望使用YAML文件中的默认值执行shell扩展,保留其结构和前导空格,以保持其可用性

例如:

version: 2

services:
    postgres: 
       image: ${POSTGRESQL_IMAGE:-my-private-registry/postgres}:${POSTGRESQL_BUILD:-9.6}"
       labels:
           io.rancher.scheduler.affinity:host_label: myproject=true

    myapp:
       image: ${APP_IMAGE:-my-private-registry/myapp}:${APP_BUILD:-latest}
       depends_on:
           - postgres
...
输出应如下所示:

version: 2

services:
    postgres: 
       image: my-private-registry/postgres:9.6
       labels:
           io.rancher.scheduler.affinity:host_label: myproject=true

    myapp:
       image: my-private-registry/myapp:latest
       depends_on:
           - postgres
...
我想获得renderes docker compose文件,以便将其传递给Rancher,Rancher只支持
版本2
,而不支持shell扩展

什么是最好和可靠的解决方案

我试过:

  • envsubt
    但它只能执行基元subsition
  • shell
    eval
    但它会删除前导空格并损坏文件

我终于找到了解决方案,即
eval
保留空间:

while IFS= read -r; do eval echo "\"""${REPLY}""\""; done < docker-compose.yml

对我来说,在shell脚本中进行变量扩展(而不是while)然后用sed替换.yml(使用更简单的关键字进行替换)似乎更容易些。

谢谢您的意见。我已经考虑过了,但是当你需要对它们进行一些转换时,我觉得它很复杂,比如默认值。通过这种方式,我希望能够使用
docker compose…
在本地主机上直接使用该文件,并使用
make…
和其他变量远程使用该文件。
while read -r; do eval echo "\"""${REPLY}""\""; done < docker-compose.yml \
   | awk 'NR==1 && ($0~"version:") {print "version: 2"}  NR!=1 {print}'