【问题标题】:Explain the effects of export LANG, LC_CTYPE, and LC_ALL [closed]解释导出 LANG、LC_CTYPE 和 LC_ALL 的影响 [关闭]
【发布时间】:2015-08-09 08:53:24
【问题描述】:

我刚刚安装了Linux Mint17,遇到了一个问题,我无法在终端中使用俄语。 (我看到的是? 而不是字母。)

在一个论坛上我找到了这个解决方案:

添加到 ~/.profile:

export LANG=ru_RU.UTF-8
export LC_CTYPE=ru_RU.UTF-8
export LC_ALL=ru_RU.UTF-8

它有所帮助,但也将我的界面语言更改为俄语(我不想要)。这甚至不是问题,但无论如何,我想知道这段代码是如何工作的(每一行)。

【问题讨论】:

标签: linux


【解决方案1】:

我会详细解释:

export LANG=ru_RU.UTF-8

这是一个shell命令,它将导出一个名为LANG的环境变量,其值为ru_RU.UTF-8。这指示国际化程序使用俄语 (ru)、来自俄罗斯的变体 (RU) 以及用于控制台输出的 UTF-8 编码。

一般这一行就够了。

另一个:

export LC_CTYPE=ru_RU.UTF-8

做类似的事情,但它告诉程序不要更改语言,而只是将 CTYPE 更改为俄语。如果程序可以将文本更改为大写,那么它将使用俄语规则来执行此操作,即使文本本身可能是英文。

值得一提的是,将LANGLC_CTYPE 混合会产生意想不到的结果,因为很少有人这样做,所以它还没有经过测试,除非可能:

export LANG=ru_RU.UTF-8
export LC_CTYPE=C

这将使程序以俄语输出,但 CTYPE 标准旧 C 风格。

最后一行LC_ALL 是最后的覆盖,这将使程序忽略所有其他LC_* 变量并使用它。我认为您永远不应该在配置文件行中编写它,而是使用它来以给定的语言运行程序。例如,如果您想编写错误报告,并且不希望任何类型的本地化输出,并且您不知道设置了哪些LC_* 变量:

LC_ALL=C program

关于更改所有程序或仅控制台的语言,这取决于您将这些行放在哪里。我将我的放在~/.bashrc 中,因此它们不适用于 GUI,仅适用于 bash 控制台。

【讨论】:

  • 这里唯一缺少的信息是他的问题的解决方案。无法使用俄语字符表明他没有使用 unicode 编码,因此LANG=en_US.UTF-8 应该允许这样做而不更改接口语言。
【解决方案2】:

请参阅 UNIX 规范页面的 Environment Variables

  • LANG 此变量确定母语的区域设置类别, 在没有LC_ALL 和 其他LC_* (LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME) 环境变量。这可以由 应用程序来确定用于错误消息的语言和 说明、整理顺序、日期格式等。

  • LC_ALL 此变量确定所有区域设置类别的值。 LC_ALL 环境变量的值优先于任何 以 LC_ 开头的其他环境变量(LC_COLLATE, LC_CTYPELC_MESSAGESLC_MONETARYLC_NUMERICLC_TIME) 和LANG 环境变量。

  • LC_CTYPE 此变量确定字符的语言环境类别 处理函数,例如tolower()toupper()isalpha()。这 环境变量决定了序列的解释 作为字符的文本数据字节(例如,single- 而不是 多字节字符),字符的分类(例如, alpha, digit, graph) 和字符类的行为。 此变量的附加语义(如果有)是 依赖于实现。

【讨论】:

  • 这并不能解释export 效果
【解决方案3】:

LANGLC_CTYPELC_ALL 是特殊的环境变量,在它们被导出到 shell 环境 (help export) 后,它们就可以被某些支持区域设置 ( C) 的自然语言格式。

每个变量都为特定的例程集设置 C 库的自然语言格式化样式概念,例如:

  • LC_ALL - 通用设置整个语言环境
  • LC_CTYPE - 为 ctypemultibyte 函数设置语言环境。这可以控制大小写、字母或非字母字符等的识别。

和其他诸如LC_COLLATE(用于字符串整理例程)、LC_MESSAGES(用于消息目录)、LC_MONETARY(用于格式化货币值)、LC_NUMERIC(用于格式化数字)、LC_TIME(用于格式化日期和时间)。

关于LANG,它被用作任何未设置的LC_* 变量的替代品(参见:man locale)。

参见:man setlocale (BSD)、man locale

所以当调用某些C函数时(如setlocalectypemultibytecatopenprintf等),它们会从配置文件和本地环境中读取区域设置为了根据 C 编程语言标准控制和格式化自然语言格式化样式(请参阅:ISO C99

另请参阅:C Library - <locale.h>

【讨论】:

  • 从程序员的角度来看(以及对 Stack Overflow 的适用性),这是最好的答案。
【解决方案4】:

export 令人困惑。 真正的意思是mark-for-export

这意味着稍后将创建子进程,这就是实际导出完成的时间。


export 事件的顺序是:1-ASSIGNMARK 和 ... 2-FORK


1)创建一个新的本地shell变量,为其赋值,并标记该变量以供稍后导出。

2) 然后,如果当前的 shell 脚本是 FORKED,(即创建和运行任何子进程),然后使用这个导出变量的副本启动一个子进程,作为它的众多环境变量之一。

nb(注意):直到第 2 步,并且可能在 export 声明发布很久之后,变量才真正被导出。 所以: export 只标记 LANG。它不导出 LANG。


按照惯例,导出的变量以大写命名。

因为LANG只是一个副本,所以如果孩子以后修改这个变量,它只是为自己修改。父级看不到子级的修改。

请注意,还有许多其他环境变量从父进程传递给子进程。这些包括父进程也从其父进程获取的所有其他环境变量。

所以子进程继承了父进程的所有环境变量,
+ 父母为export 标记的任何其他内容,
- 减去任何显式为unset 的变量。


换句话说,我们需要考虑两个进程:父进程和任何未来的子进程。

您正在运行的进程,在本例中为 profile,就是我们所说的“父进程”。

profile 可以生成一个或多个子进程,例如,如果您在配置文件中执行的一项操作是运行程序。然后该程序(通常)作为profile 的子进程运行。 (如果文件来源于配置文件,则使用. &lt;name&gt;source &lt;name&gt; 表示法,其中来源与profile 在同一进程中运行,则不是这样。)


export LANG=ru_RU.UTF-8
export LC_CTYPE=ru_RU.UTF-8
export LC_ALL=ru_RU.UTF-8

那么现在我们来看看这三个环境变量的作用。

LANG 是用户通常设置来影响程序运行的语言。在终端中,如果您输入env | grep LANG,您应该会看到 LANG 设置为您的&lt;language&gt;_&lt;country-code&gt;.&lt;character-encoding&gt;,例如LANG=en_US.UTF-8。

LC_CTYPE 是对 LANG 的覆盖,并且只覆盖所使用的字符集。 LANG 的所有其他功能(类别)仍按 LANG 设置使用,例如LC_TELEPHONE。

LC_ALL 是进一步的覆盖。它覆盖了 LC_CTYPE 和 LANG 为给定语言和代码集设置的所有语言环境类别。请注意,LC_ALL 永远不应该被永久设置,就像配置文件本身一样。它仅用于临时覆盖整个区域设置,即覆盖所有类别,如 LC_TELEPHONE、LC_MONETARY、LC_CTYPE 等。

【讨论】:

    【解决方案5】:

    您的.bashrc 文件是要读取的第一个文件之一,它包含您的shell 会话的各种配置。

    来自What's the difference between .bashrc, .bash_profile, and .environment?

    .bashrc 只能被交互式和非登录的 shell 读取

    Defining a variable with or without export中所述:

    export 使变量可用于子进程。

    特别是 export 使变量可以通过环境对子进程可用。

    摩尔

    【讨论】:

      猜你喜欢
      • 2011-12-29
      • 2010-09-25
      • 2019-08-30
      • 1970-01-01
      • 2014-09-24
      • 1970-01-01
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多