我试图了解 Linux 中的语言环境是如何工作的。我认为它是这样工作的:
每个进程都有一个环境变量表,您可以启动一个进程并使用一些语言环境变量为该进程设置一些环境变量(例如:LC_ALL=en_US.UTF-8
)。
但是,如果这个新启动的进程想要查看其语言环境变量是什么,它不会查看环境变量表,而是会查看一个单独的语言环境变量表,如下所示:
因此,如果进程想要使用在其环境变量表中设置的区域设置变量,则应首先将它们复制到其区域设置变量表中。例如,要将LC_ALL
变量从环境变量表复制到区域设置变量表中,该过程将执行以下操作:
setlocale (LC_ALL, "");
我的理解正确吗?如果我是正确的,那么所有进程都有一个区域设置变量表,还是该表仅存在于用 C 编写的程序中?
答案1
你的理解部分正确,但只是部分正确。您缺少了解的一件事是如何使用区域设置。区域设置由执行区域设置相关操作的各种库函数使用,例如翻译消息(使用LC_MESSAGES
)、格式化数字 ( LC_NUMERIC
) 和日期 ( ) LC_TIME
、编码和解码文本 ( LC_CTYPE
)、排序文本 ( LC_COLLATE
) 等。
以格式化日期的函数为例。如果要求使用与区域设置相关的格式,它将在配置为在当前进程中使用的区域设置中查找日期格式的规则。日期格式化并不关心语言环境名称,它需要知道的是如何格式化日期。因此,虽然它确实查看您所谓的“区域设置表”,但该表不包含名称(例如LC_TIME
is fr_FR
),而是包含设置(例如“短日期格式使用日-月-年的顺序,长日期格式使用月份名称janvier
,,février
……”)。
C 函数setlocale
填充进程的区域设置表中的一些条目。它需要两个参数:一个要填充的类别和一个字符串姓名为这些区域设置赋予特定值。该字符串基本上是从中加载设置的文件名。例如,setlocale(LC_TIME, "fr_FR")
基本上意味着“从文件将日期格式设置加载到进程的区域设置表中/usr/share/i18n/locales/fr_FR
”(比这更复杂,涉及其他文件,但这是基本思想)。
C 函数setlocale
有一种操作模式,它将查找环境变量。如果您给它一个空字符串而不是名称,它将根据语言环境环境变量层次结构。大多数程序都使用这种模式。再次强调,环境变量和语言环境名称影响setlocale
工作方式,而不是执行与语言环境相关的操作的函数如何工作。
语言环境设置表是标准库 ( libc
) 的一项功能,几乎所有程序都与之链接(无论它们是用哪种语言编写的)。大多数语言都提供了一种通过调用标准库setlocale
函数来设置它的方法。例如,Perl 和 Python 都具有setlocale
类似于 C 的函数。高级语言通常还可以根据环境设置区域设置,例如use locale
Perl;在 bash 中,它是自动的,但区域设置不是基于环境,而是基于同名的 shell 变量(因此,LC_COLLATE
即使不设置,eg 设置也会在 bash 中产生影响export
)。