背景说明
我们平时部署Flask/Django web项目的时候,都会把一些敏感信息放到系统的环境变量中,以免代码流出的时候泄露敏感信息,在使用命令启动项目的时候是可以正常通过`os.getenv("key")`来获取环境变量中的值,但是使用supervisor启动的时候默认是获取不到环境变量的,所以需要在supersior的配置文件中配置environment这个参数。
一般的写法如下:
environment=DB_HOST=localhost
如果包含特殊字符需要使用双引号将值包起来,如下:
environment=DB_HOST=localhost,DB_PASSWORD="test%"
问题
在我今天配置环境变量的时候一直报错,提示格式错误,错误信息如下:
for 'environment' is badly formatted : unsupported format character '"'
错误信息提示的是不支持双引号,可是我们上面说过如果有特殊字符一定要用双引号将值包起来的,那问题出在哪呢?
解决
正在我一筹莫展之际,在github看到一个issues终于发现了导致这个问题的元凶--%,是的就是这个百分号,让双引号给他背了锅!
解决办法也很简单,如果你的字符里面有%,使用%%替换。是的,就是将一个百分号,换成两个百分号。
所以我上面的配置应该写成:
environment=DB_HOST=localhost,DB_PASSWORD="test%%"
为什么
打破沙锅问到底,那为什么会出现这个问题呢?为什么两个百分号就正常了?我们使用python来解释下:
学过python的朋友应该都知道%是python中的占位符, 我们在字符串处理的时候经常使用,比如:
“tim is %d years old.”% 3
我们经常使用的有%s, %d, %c等,但是有一个不常用的被忽略了,就是%%, 它就代表“%”字符。
下面把占位符整理一下,大家就清楚了。
- %s 字符串 (采用str()的显示)
- %r 字符串 (采用repr()的显示)
- %c 单个字符
- %b 二进制整数
- %d 十进制整数
- %i 十进制整数
- %o 八进制整数
- %x 十六进制整数
- %e 指数 (基底写为e)
- %E 指数 (基底写为E)
- %f 浮点数
- %F 浮点数,与上相同
- %g 指数(e)或浮点数 (根据显示长度)
- %G 指数(E)或浮点数 (根据显示长度)
- %% 字符"%"