大家都知道linux的三剑客sed,awk,grep。其中sed更是文本编辑利器,被我们所熟知。本以为手到擒来,结果在项目中竟然翻车了。
项目的需求:
将postgres exporter 引入到生产环境中,以helm install 的方式进行安装,同时自定义其image 存储的registry,image pullSecrets, k8s replica count 等关键属性。
实施步骤:
- 下载最新的postgres exporter 的helm chart package 并解压
- 基于helm chart 的value.yaml创建新的values.yaml.template文件
- 将关键属性的值用FIXME_XXXX_FIXME样式来替换,其中,XXXX代表属性名
- 通过环境变量的方式,用sed 来将对应属性值替换:
sed -e "s/FIXME_DOCKER_REPO_FIXME/icr.io/g" \
-e "s/FIXME_IMAGE_PULL_SECRET_FIXME/${pg_exporter_pull_secret}/g" \
-e "s/FIXME_PROMETHEUS_POSTGRES_EXPORTER_DOCKER_IMAGE_TAG_FIXME/${prometheus_postgres_exporter_docker_image_tag:=latest}/g" \
-e "s/FIXME_DB_READONLY_USER_FIXME/${pg_db_user_readonly}/g" \
-e "s/FIXME_ENVIRONMENT_FIXME/${environment_name}/g" \
-e "s/FIXME_REGION_FIXME/${deployment_region}/g" \
-e "s/FIXME_DB_READONLY_USER_PASSWORD_FIXME/${pg_db_pass_readonly}/g" \
-e "s#FIXME_DB_URI_FIXME#${pg_db_uri}#g" \
${pg_exporter_tmp_file} \
> ${pg_exporter_conf_file}
- 用values.yaml.template来覆盖 helm chart 中的value.yaml
- 执行helm install
结果:
有一个属性值,pg_db_uri里一个特殊字 "&", 替换的结果出乎意料:
leileihu@leileis-mbp ~ % cat 1.txt
mytest: FIXME_MYTEST_FIXME
leileihu@leileis-mbp ~ % cat -n 1.txt
1 mytest: FIXME_MYTEST_FIXME
leileihu@leileis-mbp ~ % cat 1.txt |sed -e 's/FIXME_MYTEST_FIXME/hello&world/'
mytest: helloFIXME_MYTEST_FIXMEworld
简直有点辣眼睛,难以置信,我是谁,我在哪?。。。。
既然有错,我们就分析分析不是。可不能下次再掉到坑里了。经过一番资料搜索(本人还是比较推荐大家用google ,你懂得)。
原来‘&’在sed中是特殊字符,会将‘&’替换成的要搜索的字符"FIXME_MYTEST_FIXME"。 但是,我们可以通过“\”来转义就可以了:
leileihu@leileis-mbp ~ % cat 1.txt |sed -e 's/FIXME_MYTEST_FIXME/hello\&world/'
mytest: hello&world
所以,我们可以通过先定义一个环境变量“test”的方式将“&”转换成“\&”,再用sed 来替换:
leileihu@leileis-mbp ~ % test=$(echo "hello&world"|sed -e 's/\(.*\)&/\1\\\&/')
leileihu@leileis-mbp ~ % echo $test
hello\&world
leileihu@leileis-mbp ~ % cat 1.txt |sed -e "s/FIXME_MYTEST_FIXME/$test/"
mytest: hello&world
来吧,掌声,搞起。欢迎各位不吝指教。 当然最简单的方式是:
leileihu@leileis-mbp ~ % test=$(echo "hello&world"|sed -e 's/&/\\&/')
leileihu@leileis-mbp ~ % echo $test
hello\&world
leileihu@leileis-mbp ~ % cat 1.txt |sed -e "s/FIXME_MYTEST_FIXME/$test/"
mytest: hello&world