公司有个项目采用的是spring-boot启动方式,以前上线正常,前几天重新上线后,突然发现上传的文件名中文乱码了。我了解了一下具体情况,以前是正常的,而且测试环境也都是正常的,就是生产环境本次上线后突发从页面上传的附件中文名乱码了,同事们搞了几天也没找到原因所在,客户很强势,威胁要投诉项目组,情况十分紧急。
因为是银行的生产环境,安保级别非常高,我们很难进去查问题,只能先把要执行的命令写好,由上级领导审批,再由他们的运维执行,再告诉我们结果,所以,很不好定位。问了他们运维的有没有改启动命令,他们也说没有,我们这边上传那块代码也是很久没动了,那我觉得问题肯定是环境。
于是,我让他们执行一条命令export,查看一下当前用户的环境变量,很快收到他们的邮件,看到当前用户的LC_CTYPE=“en_US.UTF-8”,说明支持中文是没问题的,但同时也注意到有一条返回:USER=‘wasadm’,说明他们还是很规范的,使用的是非root用户运行应用。这样就很为难了,没头绪了。再次和运维人员确定,他们说确定是用wasadm用户启动应用的。于是,实在没办法,我又想让他们把root用户的locale变量给我看看,结果root用户的LC_CTYPE="en_US.ISO-8859-1“,这么说,如果他们用root用户启动应用的确会引起乱码,但他们坚持说是用wasadm启动的。那么有没有可能是他们切换用户不对,少了一个 “-” 导致环境变量没切换?
我仔细询问了他们是怎么切换用户的,他们说用su,我接着问他们,以前也是su吗,他们说以前是直接用wasadm用户登录启动的。这下明白了,他们明明是修改了启动方式的嘛,就是不承认,可能是他们觉得这两种方法没什么区别吧。
所以我很肯定地说,你们肯定是su后面少了一杠,导致用户切换了,但环境变量还是继承了root用户的,他们赶紧把原来的su wasadm 修改一下,变成su - wasadm,问题果然解决了。他们这才承认是他们的问题。
这里也提醒网友们注意,su user 和 su - user是有不同的,前者继承原用户的环境变量,后者切换到新用户的环境变量,如果用sudo, 则必需注意如下:
sudo -i -u tom locale:和su - tom是一样的效果,切换到新用户的环境变量,即使用的是tom的。
sudo -u tom locale:和su tom一样,使用是的原用户的环境变量。
这里特给一个示例:
johnny@Johnny-Z13:~$ sudo -i -u tom locale
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=zh_CN.UTF-8
LANGUAGE=
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=
johnny@Johnny-Z13:~$ sudo -u tom locale
LANG=C.UTF-8
LANGUAGE=
LC_CTYPE="C.UTF-8"
LC_NUMERIC="C.UTF-8"
LC_TIME="C.UTF-8"
LC_COLLATE="C.UTF-8"
LC_MONETARY="C.UTF-8"
LC_MESSAGES="C.UTF-8"
LC_PAPER="C.UTF-8"
LC_NAME="C.UTF-8"
LC_ADDRESS="C.UTF-8"
LC_TELEPHONE="C.UTF-8"
LC_MEASUREMENT="C.UTF-8"
LC_IDENTIFICATION="C.UTF-8"
LC_ALL=