Linux深入探索16-区域设置:locale

----- 最近更新【2022-02-03】-----

本文目录结构预览:

  • 一、简介
  • 二、查看区域设置:locale
    1、语法
    2、常用案例
    3、查看区域设置特定变量的值
  • 三、修改区域设置:update-locale
    1、update-locale
    2、修改初始化配置文件
    3、全局区域设置文件
  • 四、区域设置优先级
  • 五、类别(category)介绍
  • 六、C 排序与字典排序
  • 七、参考

一、简介

在 Unix 初期,每个人都使用 ASCII 码,因此也没有什么问题。但是,ASCII 码基于英语,而随着 Unix、Linux 以及 Internet 在世界范围的扩展,有必要设计一种新系统,从而能够处理许多语言以及大量不同的文化习俗。

多年后,开发人员开发出了一种新系统,该系统基于“区域设置(locale)”的思想,这属于 POSIX 1003.2 标准。

区域设置是特定于语言和地域的规则和数据的集合,也可以看成是一组环境变量。区域设置包括有关排序规则、日期和时间格式设置、数字和货币约定,以及字符分类的信息。例如,如果 Linux 用户选择了美国英语区域设置,那么在 Linux 中,日期消息将以格式“月-日-年”显示,而货币符号将会使用“$”表示,等。

注:
可移植操作系统接口(英语:Portable Operating System Interface,缩写为 POSIX)是 IEEE 为要在各种 UNIX 操作系统上运行软件,而定义 API 的一系列互相关联的标准的总称,其正式称呼为 IEEE Std 1003,而国际标准名称为 ISO/IEC 9945。它基本上是 Portable Operating System Interface(可移植操作系统接口)的缩写,而 X 则表明其对 Unix API 的传承。

二、查看区域设置:locale

locale 命令是 Linux 系统中多语言环境的设置接口,用来设置或查看程序运行的不同语言环境。
除 C 和 POSIX 这两个 locale 名称外,locale 的命名规则为:language[_territory[.codeset]][@modifier]
即:语言[_地区[.字符集编码]][@修饰]。如:en_US.UTF-8

1、语法

locale - 查看区域设置信息。(get locale-specific information)

语法:

locale [option]
locale [option] -a
locale [option] -m
locale [option] name...

常用选项:

  • -a,(all-locales)查看所有可用区域设置。
  • -m,(charmaps)查看所有可用字符映射。
  • -c,(category-name)显示有关环境变量的类别。
  • -k,(keyword-name)显示关环境变量的键名。

注:-c-k选项后面须带上某个环境变量参数或具体的键名才有意义。如,locale -k LC_CTYPE

2、常用案例

使用命令locale查看系统中所有区域设置的当前值。

[nosee@noseecomputer /home/git]$ locale 
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="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"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

使用命令locale -a查看系统支持哪些区域设置。

[nosee@noseecomputer /home/git]$ locale -a
C
C.UTF-8
en_US.utf8
POSIX
zh_CN.utf8
zh_SG.utf8

3、查看区域设置特定变量的值

1)如果 locale 命令后面加上 category 参数,将显示该 category 的所有值。如locale LC_CTYPE
2)如果 locale 命令后面加上 keyword 参数,将显示该 keyword 对应的值。如locale charmap

当查看某个具体参数的值时,为了让输出结果更有可读性,一般会加上-kc选项。

例:

[nosee@noseecomputer ~]$ locale -k LC_NAME
name_fmt="%d%t%g%t%m%t%f"
name_gen=""
name_mr="Mr."
name_mrs="Mrs."
name_miss="Miss."
name_ms="Ms."
name-codeset="UTF-8"
[nosee@noseecomputer ~]$ locale charmap
UTF-8
[nosee@noseecomputer ~]$ locale -c charmap
LC_CTYPE
UTF-8
[nosee@noseecomputer ~]$ locale -ck charmap
LC_CTYPE
charmap="UTF-8"
[nosee@noseecomputer ~]$ locale -ck charmap d_t_fmt
LC_CTYPE
charmap="UTF-8"
LC_TIME
d_t_fmt="%a %d %b %Y %r %Z"

例:查看有关存储时间和日期的格式。

[nosee@noseecomputer ~]$ locale -k LC_TIME
abday="Sun;Mon;Tue;Wed;Thu;Fri;Sat"
day="Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday"
abmon="Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec"
mon="January;February;March;April;May;June;July;August;September;October;November;December"
am_pm="AM;PM"
d_t_fmt="%a %d %b %Y %r %Z"
d_fmt="%m/%d/%Y"
t_fmt="%r"
t_fmt_ampm="%I:%M:%S %p"
...(省略)
week-ndays=7
week-1stday=19971130
week-1stweek=1
first_weekday=1
first_workday=2
cal_direction=1
timezone=""
date_fmt="%a %d %b %Y %r %Z"
time-codeset="UTF-8"
alt_mon="January;February;March;April;May;June;July;August;September;October;November;December"
ab_alt_mon="Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec"

三、修改区域设置:update-locale

1、update-locale

update-locale - 修改全局区域设置。(Modify global locale settings)

语法:update-locale [OPTIONS] [var=locale | var] [...]

例:将 LANG 设置为 C.UTF-8

[nosee@noseecomputer ~]$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="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"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
[nosee@noseecomputer ~]$ sudo update-locale  LANG=C.UTF-8
[nosee@noseecomputer ~]$ 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=

设置完需要重启 shell 才能生效。

如果系统上没有update-locale命令,也可以使用localectl命令来代替。
以下两个命令效果一样:
sudo update-locale LANG=C.UTF-8
sudo localectl set-locale LANG=C.UTF-8

2、修改初始化配置文件

也可以通过修改初始化文件来修改区域设置,如修改用户的.bashrc文件或.profile文件。

如,在初始化文件中添加如下一行:

export LANG="en_US.utf8"

只是临时修改的话只在命令行执行该命令就行。

3、全局区域设置文件

如果是 Debian 类系统,可以在/etc/default中找到全局区域设置文件:/etc/default/locale
update-locale命令修改的就是这个文件的内容。

如果是 Red Hat 类系统,则该文件位于:/etc/locale.conf

四、区域设置优先级

说明:

  • LANGUAGE 指定个人对语言环境值的主次偏好,例如zh_CN:en_US:en
  • LC_ALL 不是一个环境变量,实际相当于一次性设置全部的 LC_*。默认值一般都为空。
  • LC_* 可设定 locale 各种类别(category)的值,可以覆盖 LANG 的值。
  • LANG 指定默认使用的 locale 值。

注:若 LANG 或 LC_ALL 被设定为C,那么 LANGUAGE 的值将被忽视。

优先级:LANG < LC_* < LC_ALL,优先级比 LANG 高,LC_ALL 优先级最高。

LC_ALL 优先级最高,若设置了此变量,所有 LC_* 和 LANG 都会强制跟随它的值,所以一般不用。 LC_ALL 实际相当于一次设置全部的 LC_* 。

一般我们使用 LANG 来设置全部的 LC_*,而独立设置一个 LC_* 为想要的设置。比如,我设置LANG=en_US.UTF-8,设置LC_TIME=zh_GN.UTF-8,目的是为了输出中文形式的时间。如下:

[17:32 @nosee ~/Desktop]$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=en_US.UTF-8
LC_TIME=en_US.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=en_US.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=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
LC_IDENTIFICATION=en_US.UTF-8
LC_ALL=
[17:37 @nosee ~/Desktop]$ date
Wed 02 Feb 2022 05:37:05 PM CST
[17:37 @nosee ~/Desktop]$ export LC_TIME=zh_CN.UTF-8
[17:39 @nosee ~/Desktop]$ date
2022年 02月 02日 星期三 17:39:46 CST

五、类别(category)介绍

区域设置可以分为很多个类别(category),也就是多个环境变量。下表将列出一些常用的类别:

category 说明
LC_ADDRESS 地址书写方式 country_name="United States"
country_post="USA"
LC_COLLATE 字符集排序规则 collate-symb-hash-sizemb=1303
collate-codeset="UTF-8"
LC_CTYPE 语言符号及其分类,大小写转换 ctype-map-names="toupper";"tolower";"totitle"
charmap="UTF-8"
LC_MESSAGES 提示信息,错误信息, 状态信息,
标题, 标签, 按钮和菜单等
yesstr="yes"
nostr="no"
LC_MONETARY 货币格式化规则 int_curr_symbol="USD "
currency_symbol="$"
LC_NAME 姓名书写方式 name_mr="Mr."
name_miss="Miss."
LC_PAPER 默认纸张尺寸大小 height=279
width=216
LC_TELEPHONE 电话号码书写方式 tel_int_fmt="+%c (%a) %l"
int_select="11"
LC_TIME 时间显示规则 abday="日;一;二;三;四;五;六"
d_t_fmt="%Y年%m月%d日 %A %H时%M分%S秒"

使用命locale可心展开查看每个 category 的具体键值对:

[18:16 @nosee ~/Desktop]$ locale -kc LC_TIME
LC_TIME
abday="日;一;二;三;四;五;六"
day="星期日;星期一;星期二;星期三;星期四;星期五;星期六"
abmon="1月;2月;3月;4月;5月;6月;7月;8月;9月;10月;11月;12月"
mon="一月;二月;三月;四月;五月;六月;七月;八月;九月;十月;十一月;十二月"
am_pm="上午;下午"
d_t_fmt="%Y年%m月%d日 %A %H时%M分%S秒"
d_fmt="%Y年%m月%d日"
t_fmt="%H时%M分%S秒"
t_fmt_ampm="%p %I时%M分%S秒"
...
date_fmt="%Y年 %m月 %d日 %A %H:%M:%S %Z"
time-codeset="UTF-8"
alt_mon="一月;二月;三月;四月;五月;六月;七月;八月;九月;十月;十一月;十二月"
ab_alt_mon="1月;2月;3月;4月;5月;6月;7月;8月;9月;10月;11月;12月"

或者查看某个具体的值:

[18:23 @nosee ~/Desktop]$ locale -kc abday
LC_TIME
abday="日;一;二;三;四;五;六"

六、C 排序与字典排序

C 区域设置使用 ASCII 排序序列,在这种排序序列中,大写字母位于小写字母之前:ABC...XYZabc...z。该模式称为 C 排序序列

en_US 区域设置使用一种不同的排序序列,在排序序列中,小写字母和大写字母成对分组:aAbBcC...zZ。这种模式比较自然,因为它以字典顺序组织单词和字符。所以这一模式称为 字典排序序列

排列顺序比较:

C 区域设置:C 排序序列
空格字符
符号 ! “ # $ % & ‘ ( ) * + , - . /
数字 0 1 2 3 4 5 6 7 8 9
大写字母 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
更多符号 [ \ ] ^ _ `
小写字母 a b c d e f g h i j k l m n o p q u v w x y z
更多符号 { | } ~
en_US 区域设置:字典排序序列
符号 ` ^ ~ < = > | 等
数字 0 1 2 3 4 5 6 7 8 9
字母 a A b B c C d D e E f F g G h H i I j J k K l L m M n N
o O p P q Q r R s S t T u U v V w W x X y Y z Z

例:C 排序序列

[nosee@noseecomputer ~]$ cat aaa 
aaaa
AAAAAAAAAAA
bbbbbbbbbbb
CCCCCCCCCCC
[]
 dd
.ff
FF
[nosee@noseecomputer ~]$ sort aaa 
 dd
.ff
AAAAAAAAAAA
CCCCCCCCCCC
FF
[]
aaaa
bbbbbbbbbbb

例:字典排序序列

[nosee@noseecomputer ~]$ export LC_COLLATE=en_US.UTF-8
[nosee@noseecomputer ~]$ sort aaa 
[]
aaaa
AAAAAAAAAAA
bbbbbbbbbbb
CCCCCCCCCCC
 dd
.ff
FF

注:
在 en_US 区域设置中,如果字母前面有符号,将忽略符号对排序的影响。

七、参考

  • 有关更多信息,请参阅 locale , update-locale 和 localectl 手册页。
  • 《Unix & Linux 大学教程》(美)Harley Hahn 著 张杰良 译,相关章节:11.2、19.11、20.7。
  • 如何在Linux中更改或设置系统区域设置:https://www.howtoing.com/set-system-locales-in-linux
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容