文章目录
- 问题背景
- 查看C.UTF-8和en-US.UTF-8语言环境差异
- 关于locale
- 修改编码集
- centos(没验证)
- ubuntu
问题背景
我在ubuntu16.04虚拟机和英伟达盒子ubuntu18.04上分别部署了ngrest服务
用postman请求,ubuntu16.04虚拟机返回的中文是乱码,英伟达盒子ubuntu18.04不是乱码
用vi打开文件,ubuntu16.04虚拟机显示中文不是乱码,英伟达盒子ubuntu18.04是乱码
我用echo $LANG
命令查看发现(或者直接用locale
命令)
我的ubuntu16.04虚拟机显示为en_US.UTF-8
英伟达盒子ubuntu18.04显示为C.UTF-8
查看C.UTF-8和en-US.UTF-8语言环境差异
可能会有一些影响,因为它们在排序顺序、大小写关系、排序顺序、数千分隔符、默认货币符号等方面有所不同。
C.utf8=POSIX标准兼容的默认语言环境。只有严格的ASCII字符才是有效的,扩展后允许基本使用UTF-8
en_US.utf8=美式英语UTF-8语言环境。
虽然我不确定您可能遇到的具体效果,但我相信如果需要,您可以在应用程序中设置语言环境和编码。
一般来说,C指的是计算机,en_US指的是我们中说英语的人(以及其他想要同样行为的人)。
computer的意味着字符串有时更标准(但仍然是英语),因此程序的输出可以从其他程序读取。使用en_US,字符串可以得到改进,字母顺序可以得到改进(可能通过芝加哥风格规则的新规则等)。
所以更方便用户,但可能不太稳定。注意:语言环境不仅用于字符串的转换,还用于排序(字母顺序、数字(例如千位分隔符)、货币(我认为可以安全地预测美元和小数点后两位)、月份、星期几等。
在您的例子中,它只是两个地区的UTF-8版本。
一般来说,这不重要。我通常更喜欢enúUS.UTF-8,但通常不重要,在您的情况下(服务器应用程序),它应该只更改日志和错误消息(如果您使用locale.setlocale())。
您应该在应用程序中处理客户端区域设置。从其他程序读取的程序应该在打开管道之前设置C,所以这并不重要。
如你所见,也许这无关紧要。您还可以使用POSIX语言环境,也可以在Debian中定义。您可以使用locale -a获得已安装区域设置的列表。
注意:微优化将规定C/C.UTF-8语言环境:不翻译文件(gettext),以及关于排序和数字格式的简单规则,但这应仅在服务器端可见。
关于locale
参考文章:Linux深入探索16-区域设置:locale
修改编码集
centos(没验证)
- 安装编码集
localedef -v -c -i en_US -f UTF-8 C.UTF-8 - vim /etc/sysconfig/i18n
写入如下内容
LANG=“C.UTF-8”
LC_ALL=“C.UTF-8” - vim /etc/profile
export LANG=“C.UTF-8”
export LC_ALL=“C.UTF-8” - source /etc/profile
- locale
参考文章:Centos修改编码集为C.UTF-8
ubuntu
在我们英伟达盒子ubuntu18.04上执行/etc/default/locale
查看内容为:
root@ubuntu:/etc/default# vi locale
LANG="en_US.UTF-8"
在我们ubuntu16.04虚拟机上执行/etc/default/locale
内容为:
root@xy-virtual-machine:/etc/default# vi locale
# File generated by update-locale
LANG="en_US.UTF-8"
LANGUAGE="en_US:en"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
因为我们英伟达盒子是符合要求的,所以我猜想是否将虚拟机的/etc/default/locale
文件内容改成跟盒子一样就行了?
想归这么想,但是上面有一句File generated by update-locale
,我查看update-locale,貌似有特定方法能设置,,,
直接执行update-locale LANG=C.UTF-8
提示*** update-locale: Warning: LANGUAGE ("en_US:en") is not compatible with LANG (C.UTF-8). Disabling it.
,网上说不用管它,参考文章:OSSIM开源系统汉化解决方案
然后我们断开xshell,再连接,输入locale
,发现修改成功了
但是postman请求返回还是乱码,我们重启虚拟机试试,重启后连接发现,并未生效
莫非还真要修改真实文件?
我们打开/etc/default/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=
重启虚拟机,虽然修改成功了,但还是乱码
貌似这样直接修改文件是自欺欺人行为,它真实的编码不是在这统揽全局的
我们这样:
update-locale LANG=C.UTF-8
update-locale LANGUAGE=
update-locale LC_CTYPE="C.UTF-8"
update-locale LC_NUMERIC="C.UTF-8"
update-locale LC_TIME="C.UTF-8"
update-locale LC_COLLATE="C.UTF-8"
update-locale LC_MONETARY="C.UTF-8"
update-locale LC_MESSAGES="C.UTF-8"
update-locale LC_PAPER="C.UTF-8"
update-locale LC_NAME="C.UTF-8"
update-locale LC_ADDRESS="C.UTF-8"
update-locale LC_TELEPHONE="C.UTF-8"
update-locale LC_MEASUREMENT="C.UTF-8"
update-locale LC_IDENTIFICATION="C.UTF-8"
update-locale LC_ALL=
update-locale LANG=C.UTF-8 && \
update-locale LANGUAGE= && \
update-locale LC_CTYPE="C.UTF-8" && \
update-locale LC_NUMERIC="C.UTF-8" && \
update-locale LC_TIME="C.UTF-8" && \
update-locale LC_COLLATE="C.UTF-8" && \
update-locale LC_MONETARY="C.UTF-8" && \
update-locale LC_MESSAGES="C.UTF-8" && \
update-locale LC_PAPER="C.UTF-8" && \
update-locale LC_NAME="C.UTF-8" && \
update-locale LC_ADDRESS="C.UTF-8" && \
update-locale LC_TELEPHONE="C.UTF-8" && \
update-locale LC_MEASUREMENT="C.UTF-8" && \
update-locale LC_IDENTIFICATION="C.UTF-8" && \
update-locale LC_ALL=
update-locale LC_ALL=“C.UTF-8” 没用。。。
重启虚拟机,还是不行
把配置文件改成
LANG="en_US.UTF-8"
重启还是不行,,我了个去。。。。。累死我了
最后一种方法,直接加启动配置文件!
在/etc/profile
文件后面增加
#arnold add 20221117 start
chmod 777 /usr/sbin/update-locale
update-locale LANG=C.UTF-8
update-locale LC_CTYPE="C.UTF-8"
update-locale LC_NUMERIC="C.UTF-8"
update-locale LC_TIME="C.UTF-8"
update-locale LC_COLLATE="C.UTF-8"
update-locale LC_MONETARY="C.UTF-8"
update-locale LC_MESSAGES="C.UTF-8"
update-locale LC_PAPER="C.UTF-8"
update-locale LC_NAME="C.UTF-8"
update-locale LC_ADDRESS="C.UTF-8"
update-locale LC_TELEPHONE="C.UTF-8"
update-locale LC_MEASUREMENT="C.UTF-8"
update-locale LC_IDENTIFICATION="C.UTF-8"
#arnold add 20221117 end
重启虽然设置成功了,还是没用。。。请求返回依然乱码
我搞不定啊,尴尬了🤣