備忘録的なもの

ユーザセッションでロケールを変更する

Linux でロケールとユーザディレクトリの設定を行う。

普段使っている Linux マシンのロケールとして en_US.UTF-8 を設定していたのだが、 ja_JP.UTF-8 に変えたのでその記録。

背景

一応ロケール設定を変えようと思った背景について触れておく。

そもそもなんで en_US.UTF-8 を使っていたのかという部分だが、以下2つが主な理由。

  • 最初に ArchLinux を使い初めた頃日本語化まわりでのトラブルを避けたくて英語にしたのを引きずっていた
  • ホームディレクトリにある各種ユーザディレクトリ( Downloads とか Desktop とか)を英語にしておきたかった

副作用としてデスクトップ環境やウェブブラウザ等のあらゆるソフトウェアの言語設定も英語になっていたが、 それほど困っていなかったのでしばらくそのままで使っていた。

ただ、しばらく使ってるとやっぱり日本語にしたいと思うことが増えてきた。

  • ブラウザの言語設定を参照して、コンテンツが全部英語になるサイトが結構ある
    • メニュー等の単語熟語程度ならともかく、文章だと Deepl とか英和時点のお世話になることも多いので読むのに時間かかる
    • 最初は英語の勉強にもなるし良いかとも思ってたがやっぱり面倒になってきた
  • GIMP とか慣れてないソフトは日本語の解説記事とかを見ながら操作することも多いので日本語の方が楽
    • 解説記事内の日本語項目に対応するものを英語で探して「どれやねん」となることがぼちぼちあった
  • やっぱり英語より日本語の方がパッと見たときの視認性が高い
    • 単純に自分の英語力が足りてないんだろうという気はする

また、ArchLinux をしばらく使って慣れてきたこともあって、最初に英語ロケールにしておく必要性も薄れてきていた。

  • 日本語関連で面倒な事にはそうそうなることなさそうという感覚になった
    • 仮に何かあっても解決できるだろうという自信が付いたのもある
  • ユーザディレクトリの名前もロケール設定とは別で制御できると分かったこと

ということで今回の作業に至る。

設定作業

作業としては、ユーザディレクトリの設定をした上でロケールの設定を変えるという順番でやる。

最終的に以下のような状態にする。

  • ロケール
    • システムロケールは英語を維持
    • ユーザロケールは日本語に変更
  • ユーザディレクトリ
    • ディレクトリ名は英語を維持

基本的には今の状態を維持しつつ、ユーザロケールだけ日本語に変える感じ。

システムログとかはググるときに日本語より英語でググったほうが情報多そうな気がするので、 システムロケールは英語を維持することにした。

ユーザディレクトリの設定

まずはユーザディレクトリの名前を英語に固定する方から。

設定については freedesktop.org の wiki と、例によって ArchWiki のお世話になった。

ユーザディレクトリの管理には ArchWiki に書いてる様に xdg-user-dirs パッケージを使う事もできるが、 このツールはあくまで設定を生成したりローカライズを助けるためのモノなので使わなくても設定はできる。

(というより、自分の場合事前にディレクトリを一式作らせたくなくて、 その場合 xdg-user-dirs を使うと追加で設定が必要になってくるので使わない。この辺は後述)

freedesktop.org の仕様に沿うソフトウェアであれば、 各種ユーザディレクトリが必要になった場合 ${XDG_CONFIG_HOME}/user-dirs.dirs を参照するので、 単純にこれを作れば良い。

今回の様に英語ロケールでのデフォルト設定を維持したいのであればこんな感じ。

XDG_DESKTOP_DIR="$HOME/Desktop"
XDG_DOWNLOAD_DIR="$HOME/Downloads"
XDG_TEMPLATES_DIR="$HOME/Templates"
XDG_PUBLICSHARE_DIR="$HOME/Public"
XDG_DOCUMENTS_DIR="$HOME/Documents"
XDG_MUSIC_DIR="$HOME/Music"
XDG_PICTURES_DIR="$HOME/Pictures"
XDG_VIDEOS_DIR="$HOME/Videos"

一応ホントにこのファイルを参照しているかについては、 XDG_DOWNLOAD_DIR の値を適当なものに弄ってみるのが手っ取り早い。 ファイル編集後に適当なウェブブラウザで何かダウンロードリンク踏むと、 ダウンロード先のディレクトリが変わるのが確認できるはず。(要ブラウザ再起動)

ファイルを一個作っただけではあるが、これでユーザディレクトリを英語名で固定することができる。

ロケールの変更

ユーザディレクトリを英語名で固定できたので、次にロケールの設定を変更する。

自分の場合 OS インストール時に以下ファイルを作成して、システムロケールを設定している。

$ cat /etc/locale.conf
LANG=en_US.UTF-8

ユーザセッションで別のロケールを使いたい場合は、 localegen で使いたいロケールを生成した上で、 ${XDG_CONFIG_HOME}/locale.conf にファイルを作成することでシステムロケールを上書きできる。

$ grep -v '^#' /etc/locale.gen
en_US.UTF-8 UTF-8
ja_JP.UTF-8 UTF-8

$ sudo locale-gen
Generating locales...
  en_US.UTF-8... done
    ja_JP.UTF-8... done
    Generation complete.

$ locale -a
C
C.UTF-8
POSIX
en_US.utf8
ja_JP.utf8

$ echo 'LANG=ja_JP.UTF-8' >> ~/.config/locale.conf

あと若干おま環気味なので詳細は後述するが、自分の環境ではこのファイルを読み込む処理を .profile に追記している。

$ cat ~/.profile
...()...

if [ -n "$XDG_CONFIG_HOME" ] && [ -r "$XDG_CONFIG_HOME/locale.conf" ]; then
  . "$XDG_CONFIG_HOME/locale.conf"
fi

そうすると再ログイン以降、メニューなどが日本語で表示されることが確認できる。

ロケール変更前の Xfce メニュー
作業前
ロケール変更後の Xfce メニュー
作業後

余談

xdg-user-dirs を使う場合について

ユーザディレクトリの設定について、今回は使わないことにしたが xdg-user-dirs を使ったパターンでも試したのでその場合の設定についても残しておく。

必要に応じてパッケージをインストールする。

$ sudo pacman -S xdg-user-dirs

すると /etc/ にシステムのデフォルト設定もインストールされる。 大した分量でも無いし、設定ファイルのコメントに必要なことは大体書いてる感じなので目を通しておくと良さげ。

$ pacman -Ql xdg-user-dirs | grep -v '/$' | grep '/etc/'
xdg-user-dirs /etc/xdg/user-dirs.conf
xdg-user-dirs /etc/xdg/user-dirs.defaults
一応自分がインストールした際(ver. 0.18-1 )の中身を貼っておく
$ cat /etc/xdg/user-dirs.conf
# This controls the behaviour of xdg-user-dirs-update which is run on user login
# You can also have per-user config in ~/.config/user-dirs.conf, or specify
# the XDG_CONFIG_HOME and/or XDG_CONFIG_DIRS to override this
#

enabled=True

# This sets the filename encoding to use. You can specify an explicit
# encoding, or "locale" which means the encoding of the users locale
# will be used
filename_encoding=UTF-8
$ cat /etc/xdg/user-dirs.defaults
# Default settings for user directories
#
# The values are relative pathnames from the home directory and
# will be translated on a per-path-element basis into the users locale
DESKTOP=Desktop
DOWNLOAD=Downloads
TEMPLATES=Templates
PUBLICSHARE=Public
DOCUMENTS=Documents
MUSIC=Music
PICTURES=Pictures
VIDEOS=Videos
# Another alternative is:
#MUSIC=Documents/Music
#PICTURES=Documents/Pictures
#VIDEOS=Documents/Videos

ユーザディレクトリの指定としては xdg-user-dirs を使わない場合と同じような感じで、 ${XDG_CONFIG_HOME}/user-dirs.dirs にファイルを作成する。 (xdg-user-dirs を使わないパターンと指定方法が若干違うが、絶対パス or ホームディレクトリからの相対パスでどっちでも良い)

DESKTOP=Desktop
DOWNLOAD=Downloads
TEMPLATES=Templates
PUBLICSHARE=Public
DOCUMENTS=Documents
MUSIC=Music
PICTURES=Pictures
VIDEOS=Videos

また xdg-user-dirs は(少なくとも ArchLinux のパッケージの)デフォルト設定だと、 ユーザログイン時に xdg-user-dirs-update を実行して各種ディレクトリがない場合自動で作成する設定になっている。 自分の場合 ~/Public/~/Templates/ 等の使わない空ディレクトリを作られたくないので、ログイン時に実行されない様にしておく。

$ sudo sed -i -e 's/enabled=True/enabled=False/' /etc/xdg/user-dirs.conf

という感じで、今回設定したのと同じ状態にできる。

実は先にこっちの方法で設定したのだが、 インストールした上でわざわざ実行しない設定を足すくらいならインストール自体必要ないか、 という事で最終的に xdg-user-dirs パッケージは使わないことにした。

~/.config/locale.conf の読み込みタイミングについて

ユーザセッションでのロケール設定について、最初は ArchWiki に書いてる通り単純に ~/.config/locale.conf を作ったのだが、 それだけだと反映されずなんでだろうかと調べていた。

若干腑に落ちきっていないところはあるのだが、 結果から言うと systemd と自分が使っているディスプレイマネージャ( lightdm )のデフォルト設定との噛み合わせが悪そう、 という感じだった。

まず lightdm ではセッションのラッパースクリプト内で /etc/locale.conf ~/.config/locale.conf などを読み込んでいるのだが、 デフォルトのスクリプトだと LANG 変数がセットされていない場合にのみ読み込むようになっている。

若干冗長な気もするので畳むが、一応該当部分を貼っておく
$ cat /etc/lightdm/lightdm.conf | grep -v -e '^#'
[LightDM]
run-directory=/run/lightdm

[Seat:*]
session-wrapper=/etc/lightdm/Xsession

[XDMCPServer]

[VNCServer]
$ cat /etc/lightdm/Xsession | grep -A6 -e "Load profile"
# Load profile
for file in "/etc/profile" "$HOME/.profile" "/etc/xprofile" "$HOME/.xprofile"; do
    if [ -f "$file" ]; then
        echo "Loading profile from $file";
        . "$file"
    fi
done
cat /etc/profile | grep -A6 'Load profiles'
# Load profiles from /etc/profile.d
if test -d /etc/profile.d/; then
        for profile in /etc/profile.d/*.sh; do
                test -r "$profile" && . "$profile"
        done
        unset profile
fi
$ cat /etc/profile.d/locale.sh
#!/bin/sh

# load locale.conf in XDG paths.
# /etc/locale.conf loads and overrides by kernel command line is done by systemd
# But we override it here, see FS#56688
if [ -z "$LANG" ]; then
  if [ -n "$XDG_CONFIG_HOME" ] && [ -r "$XDG_CONFIG_HOME/locale.conf" ]; then
    . "$XDG_CONFIG_HOME/locale.conf"
  elif [ -n "$HOME" ] && [ -r "$HOME/.config/locale.conf" ]; then
    . "$HOME/.config/locale.conf"
  elif [ -r /etc/locale.conf ]; then
    . /etc/locale.conf
  fi
fi

# define default LANG to C if not already defined
LANG=${LANG:-C}

# export all locale (7) variables when they exist
export LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY \
       LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT \
       LC_IDENTIFICATION

ただ、 /etc/locale.conf に関しては systemd での起動時どこか早いタイミングで別途読み込みが行われているらしく、 lightdm のラッパースクリプトを実行するタイミングで既に LANG 変数がセットされているため、 読み込み処理が行われないような感じになっていた。

$ PAGER=cat man locale.conf | head -10
LOCALE.CONF(5)                                                 locale.conf                                                LOCALE.CONF(5)

NAME
       locale.conf - Configuration file for locale settings

SYNOPSIS
       /etc/locale.conf

DESCRIPTION
       The /etc/locale.conf file configures system-wide locale settings. It is read at early boot by systemd(1).

どうするか少し悩んだが、最終的には前述の設定作業の通り ~/.profile に LANG 変数の状態を問わず ~/.config/locale.conf があれば読み込むような処理を追加して解消した。

具体的に /etc/locale.conf を読み込んでいる箇所については、 気が向いたときにでももう少し調べてみようと思う。(調べなさそう)

おわりに

冒頭の背景の通り、英語ロケールでのデメリットが気になってきたので今回日本語ロケールに変更したが、 日本語ロケール故に気になることもあるかもなとは思っている。

例えば、ソフトによって日本語対応してないものもあるだろうとは思っているが、 メニューが日本語だったり英語だったりするのがどの程度気になるか、とか。

それ以外にも不満点が出てくるかも知れないが、しばらく使ってみて気になるようならまた英語ロケールに戻すかもとは思っている。 (今回色々調べたおかげで、次は ~/.config/locale.conf を修正するだけで良くなったはず)