有没有办法防止envsubst
替换$VARIABLE
?例如,我希望像这样:
export THIS=THAT
echo "dont substitute \$THIS" | envsubst
并让它返回
dont substitute $THIS
但相反,我得到了
dont substitute THAT
这样做有什么转义字符吗?
如果你给envsubst
一个变量列表,它只会替换这些变量,而忽略其他替换。我不确定它是如何工作的,但如下所示的东西似乎可以满足您的需求:
$ export THIS=THAT FOO=BAR
$ echo 'dont substitute $THIS but do substitute $FOO' | envsubst '$FOO'
dont substitute $THIS but do substitute BAR
请注意,$THIS
将保留,但$FOO
替换为 BAR
。
export DOLLAR='$'
export THIS=THAT
echo '${DOLLAR}THIS' | envsubst
或者更清楚:
export THIS=THAT
echo '${DOLLAR}THIS' | DOLLAR='$' envsubst
我的解决方法如下:
原始模板:
$change_this
$dont_change_this
编辑的模板:
$change_this
§dont_change_this
现在,您可以处理:
envsubst < $template | sed -e 's/§/$/g'
这依赖于字符§
不会出现在模板上的任何其他位置。您可以使用任何其他字符。
$ echo $SHELL
/bin/bash
$ echo $SHELL
$SHELL
$ echo $SHELL | envsubst
/bin/bash
$ echo $${q}SHELL | envsubst
$SHELL
因此,这样做$$
允许您添加$
字符。然后只需"替换"不存在的变量(这里我使用了${q}
但可以像${my_empty_variable}
这样更有意义,你最终会得到你需要的东西。
就像段落解决方案一样 - 你需要一些特别的东西 - 在这里......一个不存在的变量,比起在模板上执行额外的 sed,我更喜欢它。
如果只有一个或两个变量不想扩展,您可以通过暂时将它们设置为自己的名称来将它们列入白名单,如下所示:
$ echo 'one $two three $four' | four='$four' envsubst
one three $four
在这里,$four
变量被替换为$four
,有效地保持原样。
就我而言,我只想转义尚未定义的变量。为此,请运行:
envsubst "$(env | sed -e 's/=.*//' -e 's/^/$/g')"
"转义"某些环境变量替换的另一种方法是使用默认值赋值(或任何其他变量处理(,因为 envsubst 不会替换这些:
$ export two=2
$ echo 'one $two three ${four:-}' | envsubst
one 2 three ${four:-}
第四个 envvar 没有被替换,而在其输出中,使用 defaulkt 值的处理仍然存在。不过这并不重要,因为如果未设置变量及其值,则稍后处理此行仍将不提供任何内容。
使用的另一种选择,因为它节省了为一个程序安装整个gettext
包的过程。我有这个 awk 脚本,我调用 envtmpl
,它将任何看起来像 {{ENV-VAR}}
的环境变量交换为 ENV-VAR
#! /usr/bin/awk -f
{ for (a in ENVIRON) gsub("{{" _ a _ "}}",ENVIRON[a]); print }
所以
$ echo "My shell '{{SHELL}}' is cool" | envtmpl
My shell '/bin/bash' is cool
如您所见,如果{{
和}}
不是您喜欢的,那么它实际上都需要更改,并且此脚本可以很好地与busybox
的awk
一起使用。
不会是世界上最快的解决方案,但它真的很容易实现,我主要运行它来准备配置文件,所以速度是无关紧要的。
警告:这和envsubst
之间的唯一主要区别是,这不会改变不存在值的变量。也就是说{{HAS-NO-VALUE}}
将完全保留原样,而envsubst
将删除它们(将它们替换为空白(。
如果需要,您可以通过在awk
中添加更多代码来解决此问题。
我这样做的方式是
export DONT_CHANGE_THIS=${DONT_CHANGE_THIS}
envsubst < some-template.yml > changed.yml
因此,它将尝试将 ${var} 替换为 \${var} 作为输出,您将获得 ${var} 按原样打印
我为此使用了转义字符
MYENVVAR="${MYENVVAR}"
export MYENVVAR
envsubst #whatever you want
然后将其重置为我实际想要的
MYENVVAR="my value"
export MYENVVAR
我只是连接了其他答案的一部分来创建单行代码,该代码替换以 $ 为前缀的变量,但忽略 $$:
echo "$TEST ; $$l" > TEST_FILE
cat TEST_FILE
# $TEST ; $$l
export TEST=1
cat TEST_FILE | sed -e 's/$$/§/g' | envsubst | sed -e 's/§/$/g'
# 1 ; $l
扩展@aaron的答案,替换技术在使用 Nginx 定义的变量(如 $remote_addr(以及环境变量时有效。
就我而言,我正在从Docker运行Nginx。
我的目录结构:
docker-hello-world
├── certs/
│ ├── ssl_certificate_file.crt # SSL Certificate named in .env
│ └── ssl_key_file.key # SSL Key named in .env
├── nginx/
│ ├── .dockerignore
│ ├── Dockerfile
│ └── nginx.conf # Nginx proxy server configuration
├── hello-world/
│ ├── .dockerignore
│ ├── entrypoint.sh
│ ├── hello_world.py
│ └── Dockerfile
├── docker-compose.yml
├── environment.yml # define the modules to include in the Python virtual environment
└── .env # Application-wide environment variables
来自我的nginx/Dockerfile:
FROM nginx:latest
RUN apt-get update && rm -rf /var/lib/apt/lists/* && rm -rf /etc/nginx/user.conf.d/*
RUN touch /etc/nginx/nginx.conf;
envsubst "$(env | sed -e 's/=.*//' -e 's/^/$/g')" < /etc/nginx/templates/default.conf.template > /etc/nginx/nginx.conf;