labunix's blog

labunixのラボUnix

debian stretchを令和に対応してみる。

■debian stretchを令和に対応してみる。

$ lsb_release -d
Description:	Debian GNU/Linux 9.9 (stretch)2019/05/01は平成31年で表示される。
 これはlocalesパッケージの設定依存らしい。

 Red Hat Enterprise Linux における日本の元号処理
 https://jp-redhat.com/openeye_online/column/oss-note/5547/

$ LC_ALL=ja_JP.utf8 date +%EY -d 20190501
平成31年

■RHELもそうなら、debianもそうかも。

$ ldd `which date`
	linux-vdso.so.1 (0x00007ffff83c6000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2f20255000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f2f2080e000)

$ apt-file search libc.so.6 | grep libc6:
libc6: /lib/x86_64-linux-gnu/libc.so.6

■なるほど。「どこかで日本語に変換する」という考え方では、glibcよりlocalesの方が納得がいく。

$ LC_TIME=ja_JP.utf8 ltrace date +'%EY' 2>&1 | grep "locale"
setlocale(LC_ALL, "")                            = "LC_CTYPE=ja_JP.UTF-8;LC_NUMERIC="...
bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"

$ LC_ALL=ja_JP.utf8 strace date +%EY -d 20190501 2>&1 | grep locale
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
open("/usr/share/locale/ja_JP.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/ja_JP/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/ja.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/ja/LC_MESSAGES/coreutils.mo", O_RDONLY) = 3

$ apt-file search locales | grep "locales/ja_JP\$"
locales: /usr/share/i18n/locales/ja_JP

$ dpkg -l | awk '$1 ~ /^ii/&&$2 ~ /^locales/{gsub("   *",",",$0);print $0}'
ii,locales,2.24-11+deb9u4,all,GNU C Library: National Language (locale) data [support]

■該当箇所を書き換え。

$ sudo cp /usr/share/i18n/locales/ja_JP{,.org}

$ diff /usr/share/i18n/locales/ja_JP*
14952,14954c14952
< era    "<U002B><U003A><U0032><U003A><U0032><U0030><U0032><U0030><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U002B><U002A><U003A><U4EE4><U548C><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
<        "<U002B><U003A><U0031><U003A><U0032><U0030><U0031><U0039><U002F><U0030><U0035><U002F><U0030><U0031><U003A><U0032><U0030><U0031><U0039><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U4EE4><U548C><U003A><U0025><U0045><U0043><U5143><U5E74>";/
<        "<U002B><U003A><U0032><U003A><U0031><U0039><U0039><U0030><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0032><U0030><U0031><U0039><U002F><U0030><U0034><U002F><U0033><U0030><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
---
> era	"<U002B><U003A><U0032><U003A><U0031><U0039><U0039><U0030><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U002B><U002A><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/

■以下のURLに上記の4行を入力してみる。

 Unicode Escape Sequence | KWONLINE.ORG
 https://www.kwonline.org/u_esc_seq.php

$ diff /usr/share/i18n/locales/ja_JP* | awk -F\" '/<U/{gsub("<","\134",$0);gsub(">","",$0);print tolower($2)}'
\u002b\u003a\u0032\u003a\u0032\u0030\u0032\u0030\u002f\u0030\u0031\u002f\u0030\u0031\u003a\u002b\u002a\u003a\u4ee4\u548c\u003a\u0025\u0045\u0043\u0025\u0045\u0079\u5e74
\u002b\u003a\u0031\u003a\u0032\u0030\u0031\u0039\u002f\u0030\u0035\u002f\u0030\u0031\u003a\u0032\u0030\u0031\u0039\u002f\u0031\u0032\u002f\u0033\u0031\u003a\u4ee4\u548c\u003a\u0025\u0045\u0043\u5143\u5e74
\u002b\u003a\u0032\u003a\u0031\u0039\u0039\u0030\u002f\u0030\u0031\u002f\u0030\u0031\u003a\u0032\u0030\u0031\u0039\u002f\u0030\u0034\u002f\u0033\u0030\u003a\u5e73\u6210\u003a\u0025\u0045\u0043\u0025\u0045\u0079\u5e74
\u002b\u003a\u0032\u003a\u0031\u0039\u0039\u0030\u002f\u0030\u0031\u002f\u0030\u0031\u003a\u002b\u002a\u003a\u5e73\u6210\u003a\u0025\u0045\u0043\u0025\u0045\u0079\u5e74

■上記URLの変換結果は以下のようになって、平成が1990/01/01以降ずっとという定義を削除して、
 令和の定義を追加するパッチになっていることが分かる。

+:2:2020/01/01:+*:令和:%EC%Ey年
+:1:2019/05/01:2019/12/31:令和:%EC元年
+:2:1990/01/01:2019/04/30:平成:%EC%Ey年
+:2:1990/01/01:+*:平成:%EC%Ey年

■localesの更新で反映する。

$ man localedef | grep -A 1 "/usr/share/i18n/charmaps"
       /usr/share/i18n/charmaps
              Usual default character map path.

$ localedef --list-archive
ja_JP.utf8

$ sudo localedef -f UTF-8 -i ja_JP ja_JP.utf8

$ strings /usr/lib/locale/locale-archive | grep 2019
+:1:2019/05/01:2019/12/31:
+:2:1990/01/01:2019/04/30:

■debianユーザなら、上記よりも以下の方が慣れ親しんでいるかも知れない。
 localesの更新がされれば問題ない。

$ sudo dpkg-reconfigure locales
Generating locales (this might take a while)...
  ja_JP.UTF-8... done
Generation complete.

■結果を見てみる。

$ LC_ALL=ja_JP.utf8 date +%EY -d 20190501
令和元年

$ LC_ALL=ja_JP.utf8 date +%EY -d 20190430
平成31年

■設定を戻してみる。

$ sudo cp /usr/share/i18n/locales/ja_JP{,.bak}
$ sudo mv /usr/share/i18n/locales/ja_JP{.org,}
$ sudo diff /usr/share/i18n/locales/ja_JP{,.bak}
14952c14952,14954
< era	"<U002B><U003A><U0032><U003A><U0031><U0039><U0039><U0030><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U002B><U002A><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
---
> era    "<U002B><U003A><U0032><U003A><U0032><U0030><U0032><U0030><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U002B><U002A><U003A><U4EE4><U548C><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
>        "<U002B><U003A><U0031><U003A><U0032><U0030><U0031><U0039><U002F><U0030><U0035><U002F><U0030><U0031><U003A><U0032><U0030><U0031><U0039><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U4EE4><U548C><U003A><U0025><U0045><U0043><U5143><U5E74>";/
>        "<U002B><U003A><U0032><U003A><U0031><U0039><U0039><U0030><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0032><U0030><U0031><U0039><U002F><U0030><U0034><U002F><U0033><U0030><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/

$ sudo dpkg-reconfigure locales
Generating locales (this might take a while)...
  ja_JP.UTF-8... done
Generation complete.

$ LC_ALL=ja_JP.utf8 date +%EY -d 20190501
平成31年

■戻し方も分かったので、しばらく令和対応にしておこう。

$ sudo cp /usr/share/i18n/locales/ja_JP{.bak,}
$ sudo dpkg-reconfigure locales
Generating locales (this might take a while)...
  ja_JP.UTF-8... done
Generation complete.
$ LC_ALL=ja_JP.utf8 date +%EY -d 20190501
令和元年

■sidには適用されているのかも。

 glibc: deal with Japanese new era "令和 (Reiwa)"
 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=927914

$ dpkg -L libc-bin | grep LC_TIME
/usr/lib/locale/C.UTF-8/LC_TIME

$ apt-file search LC_TIME | awk '{a[$1]+=1}END{for(n in a){print a[n],n}}'
35 dc3dd:
16 rust-doc:
5 abook:
4 cakephp:
477 locales-all:
1 libc-bin:

$ apt-file search LC_TIME | grep libc-bin
libc-bin: /usr/lib/locale/C.UTF-8/LC_TIME