- envsubst可以將一個文件中的占位符標志如${xxx}/$xxx用環境變量替換掉。因此可以用來動態注入nginx的配置。在使用docker鏡像時通過這個方式可以實現較為方便地修改ng反向代理配置。
- 但是此時會存在一個問題,nginx約定好的$host/$remote等變量也會被這個命令替換掉,基本上都會造成問題。
- 但envsubst還有一個參數,就是只替換指定的環境變量,這樣就不會替換掉nginx約定好的變量了。
- 但是環境變量是不確定有哪些的,或者說,如果環境變量較多時,一個個指定也很麻煩
解決方法
拿到當前環境所有已定義的環境變量,使用文本處理,得到所有想要替換的環境變量。此時使用envsubst指定替換功能,就不會替換掉$host/$remote等信息了
nginx官方是這么做的,此文件來自nginx鏡像。妙啊
#!/bin/sh
set -e
ME=$(basename $0)
auto_envsubst() {
local template_dir="${NGINX_ENVSUBST_TEMPLATE_DIR:-/etc/nginx/templates}"
local suffix="${NGINX_ENVSUBST_TEMPLATE_SUFFIX:-.template}"
local output_dir="${NGINX_ENVSUBST_OUTPUT_DIR:-/etc/nginx/conf.d}"
local template defined_envs relative_path output_path subdir
# 這里拿到了所有定義的環境變量
# [root@iZwz9hmxhr8nh716gmser4Z tmp]# printf '${%s} ' $(env | cut -d= -f1)
# ${XDG_SESSION_ID} ${HOSTNAME} ${TERM} ${SHELL} ${HISTSIZE} ${SSH_CLIENT} ${NNHOST} ${OLDPWD} ${SSH_TTY} ${NGINX_HOST} ${USER} ${LS_COLORS} ${MAIL} ${PATH} ${PWD} ${LANG} ${HISTCONTROL} ${SHLVL} ${HOME} ${LOGNAME} ${SSH_CONNECTION} ${LESSOPEN} ${XDG_RUNTIME_DIR} ${_}
defined_envs=$(printf '${%s} ' $(env | cut -d= -f1))
[ -d "$template_dir" ] || return 0
if [ ! -w "$output_dir" ]; then
echo >&3 "$ME: ERROR: $template_dir exists, but $output_dir is not writable"
return 0
fi
find "$template_dir" -follow -type f -name "*$suffix" -print | while read -r template; do
relative_path="${template#$template_dir/}"
output_path="$output_dir/${relative_path%$suffix}"
subdir=$(dirname "$relative_path")
# create a subdirectory where the template file exists
mkdir -p "$output_dir/$subdir"
echo >&3 "$ME: Running envsubst on $template to $output_path"
# 這里指定只替換定義的環境變量,因此不會覆蓋掉nginx約定好的$host...等變量
# 相當於執行了
# envsubst "${XDG_SESSION_ID} ${HOSTNAME} ${TERM} ${SHELL} ${HISTSIZE} ${SSH_CLIENT} ${NNHOST} ${OLDPWD} ${SSH_TTY} ${NGINX_HOST} ${USER} ${LS_COLORS} ${MAIL} ${PATH} ${PWD} ${LANG} ${HISTCONTROL} ${SHLVL} ${HOME} ${LOGNAME} ${SSH_CONNECTION} ${LESSOPEN} ${XDG_RUNTIME_DIR} ${_}" <"$template" >"$output_path"
envsubst "$defined_envs" <"$template" >"$output_path"
done
}
auto_envsubst
exit 0