为什么 Encoding.default_external 不尊重 LANG?

Jim*_*dra 0 ruby ascii utf-8 character-encoding

我的理解是,Ruby 的Encoding.default_external默认值基于环境变量LC_ALLLANG,优先于前者。我遇到了几个错误,即使环境变量设置为 UTF-8,默认外部编码也会以某种方式最终设置为 ASCII。

例如:

$ irb
irb(main):001:0> Encoding.default_external
=> #<Encoding:US-ASCII>
irb(main):002:0> ENV['LC_ALL']
=> nil
irb(main):003:0> ENV['LANG']
=> "en_US.UTF-8"
Run Code Online (Sandbox Code Playgroud)

在发生这种情况的环境中,我还搜索了所有为手动设置默认外部编码的代码加载的 gem,但没有找到任何东西。我在上面看到的怎么可能?我在上面使用 Ruby 2.2,但我已经看到这种情况发生在所有 Ruby 2.x 版本上。

Jim*_*dra 5

我想到了。不仅LANG需要设置环境变量,而且必须为操作系统生成它所指定的语言环境。在库存 Linux 映像上,默认语言环境可能不是 UTF-8。在我的特殊情况下,我使用的是 Debian 7.7,默认语言环境是“POSIX”。我能够通过安装 locales 包并按照交互式提示生成 en_US.UTF-8 语言环境来设置默认语言环境:

$ apt-get -y install locales
Run Code Online (Sandbox Code Playgroud)

如果 locales 包已经安装,你可以重新配置它:

$ dpkg-reconfigure locales
Run Code Online (Sandbox Code Playgroud)

现在设置LANG将更改当前系统区域设置,并且 RubyEncoding.default_external将正确设置:

$ export LANG=en_US.UTF-8
$ 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=
$ irb
irb(main):001:0> Encoding.default_external
=> #<Encoding:UTF-8>
Run Code Online (Sandbox Code Playgroud)

有关如何自动生成和配置默认语言环境而不是以交互方式进行的示例,请查看此 Docker 映像

  • 我有同样的问题,但这并没有解决它,在安装语言环境并设置 LANG 变量后,我仍然有 US-ASCII。 (3认同)