15
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【ja_JP.UTF-8】Linuxのロケールをroot権限なしでインストールする

Last updated at Posted at 2018-01-12

どうも。
Linuxには、Localeという概念があります。これはLinuxディストリビューションの標準ライブラリであるgettextdateなど、言語や地域で表示が異なる部分を共通化して切り出したものです。
これにより、OSが扱う文字コードや文字の種類、通貨の単位や年月日の表記の順番を設定することができます。
通常、このロケールは、Linuxに標準的にインストールされています。
しかし、環境によっては「en_US.UTF-8が無い!?」「日本語使いたいけどja_JP.UTF-8入ってないんだけど!」ということがあります。それが自分のマシンではなく、共有マシンの場合、root権限を持っているユーザーは一部だけなため、なおさら解決が難しいです。

そのため、今回は、ロケールをユーザー権限で新たにインストールし、利用できるようにします。

前提知識

パス 意味
/usr/share/locale ロケールの設定ファイルなどが収められている。
/usr/lib/locale/ ロケールの本体。ロケールがディレクトリごとに収められている。
/usr/lib/locale/locale-archive ロケールの本体。上はディレクトリごとだが、こちらはディレクトリをまとめて書庫の形式にしたもの。こちらほうが総容量が少なくて済む。
/usr/share/i18n/locales ロケールの書庫や設定ファイルを作り出すためのソースコードが入っている。
/etc/locale.gen locale-genコマンドで自動で生成するロケール一覧
/etc/locale.conf システムで利用するロケール
コマンド できること
locale インストールされているロケール一覧を取得した、今どのロケールが利用されているか確認できる。
locale-gen localedefのラッパー。/etc/locale.genファイルに書いてあるロケールを生成する。
localedef ロケールを生成するコンパイラ。

考えてみる

通常はlocale-genを使い、localeをコンパイル・インストールしているが、今回は/etc/locale.confを編集できず、そもそも/usr/以下への書き込み権限がない。

ということなので、locale-genはlocaledefのラッパースクリプトなので、localedefを直接調べてみましょう。
するとlocaledefのオプションがわかりました。

使用法: localedef [OPTION...] NAME
または:  localedef [OPTION...]
            [--add-to-archive|--delete-from-archive] FILE...
または:  localedef [OPTION...] --list-archive [FILE]
ロケール仕様をコンパイルする

 入力ファイル:
  -f, --charmap=FILE         シンボル文字名は FILE
                             内で定義されています
  -i, --inputfile=FILE       FILE 内でソース定義が見つかりました

  -u, --repertoire-map=FILE  FILE にはシンボル名から UCS4
                             値へのマップが含まれます

 出力制御:
  -c, --force
                             警告メッセージがあっても出力を作成する
      --posix                Strictly conform to POSIX
      --prefix=PATH
                             出力ファイルにオプションの接頭辞を付加する
      --quiet                警告と情報メッセージを抑制する
  -v, --verbose              詳細なメッセージを表示する

 書庫制御:
      --add-to-archive
                             パラメータで指定された名前のロケールを書庫に追加する
  -A, --alias-file=FILE      書庫を作成する時に locale.alias
                             ファイルを参照する
      --big-endian           Generate big-endian output
      --delete-from-archive
                             パラメータで指定された名前のロケールを書庫から削除する
      --list-archive         書庫の内容のリストを表示する
      --little-endian        Generate little-endian output
      --no-archive           書庫に新しいデータを追加しない
      --replace              既存の書庫の内容を置換する

  -?, --help                 このヘルプ一覧を表示する
      --usage                短い使用方法を表示する
  -V, --version              プログラムのバージョンを表示する

とここでprefixというオプションを発見しました。これを色々と弄った結果、書庫を生成することができました!
で、問題は設定ファイルの方(/usr/share/locale)です。それについても、localedefに与えるオプションで解決できました。

# 設定ファイルの作成
$ localedef -i /usr/share/i18n/locales/ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias /home/user/mylocale/ja_JP.UTF-8

# 書庫の作成
$ mkdir -p /home/user/locale/usr/lib/locale
$ localedef -i /usr/share/i18n/locales/ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias --add-to-archive --prefix=/home/user/locale
# prefixで指定したディレクトリ以下のusr/lob/locale/locale-archiveに書庫が生成されます。直接ディレクトリは指定できないようです 。

と、ここで問題の解決ができたのですが、これでは毎回手動で生成することになりますし、めんどくさいです。
と、ここで、locale-genを思い出しました。これは、localedefをラップして、/etc/locale.genに指定したロケールを自動でコンパイルしてくれるじゃないですか。
ということなので、locale-genをいじって、ローカルインストールも自動化しちゃいましょう!

ということで以下。

locale-gen.local
#!/bin/bash

set -e

if [[ -z "$MYLOCAL" ]];then
        echo '$MYLOCAL is not set.'
        exit
fi

LOCALEGEN=$MYLOCAL/etc/locale.gen
LOCALES=/usr/share/i18n/locales
USER_LOCALES=/usr/local/share/i18n/locales
LOCALE_ARCHIVE=$MYLOCAL/usr/lib/locale

if [ -n "$POSIXLY_CORRECT" ]; then
  unset POSIXLY_CORRECT
fi

[ -f $LOCALEGEN ] || exit 0;
[ -s $LOCALEGEN ] || exit 0;

KEEP=
if [ "$1" = '--keep-existing' ]; then
        KEEP=1
fi

if [ -z "$KEEP" ]; then
        # Remove all old locale dir and locale-archive before generating new
        # locale data.
        rm -rf $LOCALE_ARCHIVE/locale-archive || true
fi

umask 022

is_entry_ok() {
  if [ -n "$locale" -a -n "$charset" ] ; then
    true
  else
    echo "error: Bad entry '$locale $charset'"
    false
  fi
}

echo "Generating locales (this might take a while)..."
while read locale charset; do \
        case $locale in \#*) continue;; "") continue;; esac; \
        is_entry_ok || continue
        if [ "$KEEP" ] && PERL_BADLANG=0 perl -MPOSIX -e \
            'exit 1 unless setlocale(LC_ALL, $ARGV[0])' "$locale"; then
                continue
        fi
        echo -n "  `echo $locale | sed 's/\([^.\@]*\).*/\1/'`"; \
        echo -n ".$charset"; \
        echo -n `echo $locale | sed 's/\([^\@]*\)\(\@.*\)*/\2/'`; \
        echo -n '...'; \
        if [ -f $USER_LOCALES/$locale ] ; then
            input=$USER_LOCALES/$locale
        elif [ -f $LOCALES/$locale ]; then
            input=$locale
        else
            input=`echo $locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`
            if [ -f $USER_LOCALES/$input ]; then
                input=$USER_LOCALES/$input
            fi
        fi
        localedef -i $input -c -f $charset -A /usr/share/locale/locale.alias $LOCALE_ARCHIVE/$locale || :; \
        echo ' done'; \
        localedef -i $input -c -f $charset -A /usr/share/locale/locale.alias --add-to-archive --prefix=$MYLOCAL|| :; \
done < $LOCALEGEN
echo "Generation complete."

まず、/etc/locale.gen$MYLOCAL/etc/locale.confにコピーし、編集してください。
次に、mkdir -p $MYLOCAL/usr/lib/localeしてディレクトリを生成してください。
次にlocale-gen.config(上のシェルスクリプト)を実行します。
そうすると、$MYLOCAL/etc/locale.confにかいたロケールが全自動で生成され、$MYLOCAL/usr/lib/locale以下にロケールの設定ファイル群と書庫がインストールされます。

ローカルインストールしたロケールの選択

環境変数$LOCPATHにディレクトリを指定することで読み込むようになります。
また、ロケール自体は$LANGを設定することで指定できます。

ということで以下を.bashrcなどに追記しましょう。

export LANG=ja_JP.UTF-8
export LOCPATH=$MYLOCAL/usr/lib/locale

また、注意なのですが、こうして$LOCPATHを指定すると、標準でシステムにインストールされているロケール群を読みに行かなくなります。よって、ロケールをローカルインストールする場合、必要なロケールをすべてローカルにインストールする必要があります。
なので、root権限を所有している場合、今回の記事の内容は実践しないほうが良いです。


これでen_US.UTF-8ja_JP.UTF-8がインストールされていない鬼畜な環境でも、特定のロケールでしか動作しないバイナリなどを実行することができますね!!
ぜひ活用してみてください!

15
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?