CentOS Stream 8でFailed to set locale, defaulting to C.UTF-8と表示される

事象

以下の様な環境でdnfコマンド等を実行した際に、「Failed to set locale, defaulting to C.UTF-8」というメッセージが表示されます。

  • minimal installのCentOS Stream 8
  • インストール時に日本語ロケールを設定
  • メッセージが表示されるのは、SSHではなくコンソール(TERM=linux)を利用時

状況調査

現在の状況を確認してみます。

# localectl
   System Locale: LANG=ja_JP.UTF-8
       VC Keymap: jp
      X11 Layout: jp

# localectl list-locales
C.utf8
ja_JP.eucjp
ja_JP.utf8

# cat /etc/locale.conf
LANG="ja_JP.UTF-8"

# echo $TERM
linux

# echo $LANG
en_US.UTF-8

システムロケールはja_JP.UTF-8が設定されていて、localectl list-localesの一覧には表現こそ異なるもののja_JP.utf8が含まれています。
気になる点としては、システムロケールがja_JP.UTF-8であるにも関わらず、実際に設定されている$LANGen_US.UTF-8であることです。

色々試してみる

# dnf info perl
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 2:46:38 ago on Sat May 8 12:47:03 2021.
Available Packages
Name : perl
(..snip..)

# LANG=C dnf info perl
Last metadata expiration check: 2:47:03 ago on Sat May 8 12:47:03 2021.
Available Packages
Name : perl
(..snip..)

# LANG=ja_JP.UTF-8 dnf info perl
■■■■■■■■■■■■■■■: 2:47:20 ■■■■ 2021■05■08■ 12■47■03■ ■■■■■■■■
■■■■■■■■■■
■■ : perl
(..snip..)

# LANG=ja_JP.utf8 dnf info perl
■■■■■■■■■■■■■■■: 2:47:20 ■■■■ 2021■05■08■ 12■47■03■ ■■■■■■■■
■■■■■■■■■■
■■ : perl
(..snip..)

$LANGを設定した場合は、Failed to set locale, defaulting to C.UTF-8と表示されないことが分かりました。
(その代わり日本語を設定した場合は文字化けします。)

ここまでから、LANG=en_US.UTF-8が設定されていることが直接原因であり、localectl list-localeen_US.UTF-8が含まれていないことが根本原因であると推測されます。

では、システムロケールとは異なるLANG=en_US.UTF-8が設定されている原因から確認していきます。

# cat /etc/profile
(..snip..)
    for i in /etc/profile.d/*.sh; do
        if [ -r "$i" ]; then
            if [ "$PS1" ]; then
                . "$i"
            else
                . "$i" >/dev/null
            fi
        fi
    done
(..snip..)

# cat /etc/profile.d/lang.sh
(..snip..)
# The ${LANG} manipulation is necessary only in virtual terminal (a.k.a. console - /dev/tty*):
if [ -n "${LANG}" ] && [ "${TERM}" = 'linux' ] && /usr/bin/tty | /usr/bin/grep --quiet -e '/dev/tty'; then
    if /usr/bin/grep --quiet -E -i -e '^.+\.utf-?8$' <<< "${LANG}"; then
        case ${LANG} in
            ja*)    LANG=en_US.UTF-8 ;;
(..snip..)

ログイン時に/etc/profileが読み込まれます(詳細は割愛)。
その中でさらに、/etc/profile.d/*を読み込むようになっていました。

/etc/profile.d/の中には複数のシェルスクリプトが含まれていますが、そのうちlang.shを参照するとLANG=en_US.UTF-8を設定している行が見つかります。
$TERMlinux(コンソール)の場合に、LANG=en_US.UTF-8を設定するようになっていますね。
おそらく、コンソールでは日本語等の文字が表示できない(文字化けする)ため、あえて英語ロケールへ変更するようにしているのでしょう。

jfbterm等の異なるフレームバッファを利用すれば、コンソールでも日本語を表示することは可能です。

なお実際に、SSHでサーバへ接続すればLANG=ja_JP.UTF-8となっていることが確認できます。
コンソールを利用する場合にのみこの問題が発生するわけですね。

en-US.UTF-8が設定されている原因は判明したので、en-US.UTF-8が正常に扱えるようにすれば解決しそうです。
調べて見ると英語ロケールに必要なパッケージをインストールすれば良いことが分かりました。

解決

# dnf install glibc-langpack-en
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 2:57:31 ago on Sat May 8 12:47:03 2021.
Dependencies resolved.
========================================================================================================================
Package Architecture Version Repository Size
========================================================================================================================
Installing:
glibc-langpack-en x86_64 2.28-158.el8 baseos 827 k

Transaction Summary
========================================================================================================================
Install 1 Package
(..snip..)

# localectl list-locales
C.utf8
(..snip..)
en_US
en_US.iso885915
en_US.utf8
(..snip..)
ja_JP.eucjp
ja_JP.utf8

# dnf info perl
Last metadata expiration check: 2:58:52 ago on Sat 08 May 2021 12:47:03 PM JST.
Available Packages
Name : perl
(..snip..)

このように、「Failed to set locale, defaulting to C.UTF-8」というメッセージが表示されなくなり、無事解決する事ができました。
めでたしめでたし。

ちなみに、この事象が発生した際にググってみたのですが、かなり怪しい解決法が掲載されたページばかりでした。
発生している原因をきちんと掴むことが肝心ですね。

おすすめ

コメントを残す

Amazon プライム対象