如何使“localedef”的结果在“dpkg-reconfigure locales”中保留下来?

如何使“localedef”的结果在“dpkg-reconfigure locales”中保留下来?

我使用的是 UB 16.04 LTS 服务器,昨天更新了区域设置-软件包已发布并安装:

Start-Date: 2019-02-21  09:44:05
Commandline: /usr/bin/apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold dist-upgrade
Upgrade: [...], locales:amd64 (2.23-0ubuntu10, 2.23-0ubuntu11), [...]
End-Date: 2019-02-21  09:44:45

windows-1252另外,由于历史原因,我还使用依赖字符集的数据库 PostgreSQL 11 :

Name  |  Owner   | Encoding |   Collate    |    Ctype     |   Access[...]
------+----------+----------+--------------+--------------+--------------
[...] | postgres | WIN1252  | de_DE.CP1252 | de_DE.CP1252 |

为了使其可用,使用以下命令:

localedef -f CP1252 -i /usr/share/i18n/locales/de_DE /usr/lib/locale/de_DE.CP1252

使用locale-genbefore/afterlocaledef会出现以下错误:

locale-gen de_DE.CP1252
Error: 'de_DE.CP1252' is not a supported language or locale

该错误消息是正确的,该文件/usr/share/i18n/SUPPORTED不包含我的语言环境。据我所知,这就是我需要使用的原因localedef

现在的问题是,很可能在locales安装了新的包之后,我手动添加的包被自动删除,并且依赖该语言环境的数据库的访问失败:

2019-02-21 09:42:45.109 CET [27039] FATAL:  Datenbank-Locale ist inkompatibel mit Betriebssystem
2019-02-21 09:42:45.109 CET [27039] DETAIL:  Die Datenbank wurde mit LC_COLLATE »de_DE.CP1252« initialisiert, was von setlocale() nicht erkannt wird.

据我了解,所有被识别和启用的区域设置dpkg-reconfigure locales都已保留,而我的自定义区域设置未列在其中。因此,我按照说明/etc/locale.gen创建了以下文件,其中包含以下行:

/usr/local/share/i18n/SUPPORTED
de_DE.CP1252 CP1252

最终,我的语言环境变得可用:

在此处输入图片描述

问题是,这似乎不足以解决我的目标:每当我运行 时dpkg-reconfigure locales,使用 创建的语言环境localedef就会从文件夹中删除/usr/lib/locale/de_DE.CP1252,并且 Postgres 再次失败。即使locale -a打印了我的语言环境等。所以这很可能是在安装新 -package 时/之后发生的情况locales。如果我localedef再次按照上述说明手动运行,Postgres 会立即再次允许访问旧数据库。

我注意到一件有趣的事情,就是语言环境像我的自定义语言环境一样C.UTF-8可用/usr/lib/locale,但由于某种原因,它永远不会被自动删除。在网上搜索该语言环境,似乎它是作为某个软件包的一部分由发行版提供的,而不是根据需要在本地配置和生成的:

我们现在有一个“可卸载”的 C.UTF-8 语言环境,即使您删除语言环境存档或更改为语言环境存档安装的语言设置,它仍然可用。

https://bugzilla.redhat.com/show_bug.cgi?id=902094#c20

/usr/lib/locale/C.UTF-8/LC_ADDRESS
/usr/lib/locale/C.UTF-8/LC_COLLATE

https://packages.debian.org/de/sid/sh4/libc-bin/filelist

那么,我需要做什么才能使我的localedef结果存活下来,或者在安装新的包dpkg-reconfigure locales期间所做的一切`locales

谢谢!

答案1

这里有不同的事情需要注意:

删除 localedef 的结果

手动创建的结果localedef总是被删除,只是因为locale-gen 是一个脚本这样做:

if [ -z "$1" ] && [ -z "$KEEP" ]; then
        # Remove all old locale dir and locale-archive before generating new
        # locale data.
        rm -rf /usr/lib/locale/locale-archive || true
        for dir in /usr/lib/locale/*; do
                [ -e "$dir" ] || continue
                if [ "${dir#/usr/lib/locale/}" = C.UTF-8 ]; then
                        # owned by libc-bin
                        continue
                fi
                rm -rf "$dir" 2>/dev/null || true
        done
fi

为了避免这种情况,确实需要以不同的方式提供语言环境,以便在生成语言环境时始终生成它。

/usr/local/share/i18n/SUPPORTED

该文件实际上是使我的语言环境可用的正确方法,并且我添加它的方式也正确。该行de_DE.CP1252 CP1252导致使用与手动dpkg-reconfigure locales使用相同的语言环境localedef。唯一的区别是,在第一种情况下,语言环境被添加到文件中/usr/lib/locale/locale-archive,而后者创建单独的目录。这种差异导致以下问题...

Postgres 无法识别更改

在执行测试后,我根本没有重新启动 Postgres,dpkg-reconfigure locales但这是必要的!

当使用 where 创建的单个目录localedef被删除或添加时,只要创建了使用该语言环境的数据库会话,Postgres 就会立即识别出来。这就是为什么我认为语言环境总是根据需要读取,但事实似乎并非如此。相反,我猜想存档文件每个进程只打开一次,并且只有当其中找不到某个语言环境时,才会识别其他目录,并且是按需的。因此,当存档文件被删除并新建时,Postgres 根本无法识别,并且仍然使用旧内容,而旧内容从未包含我的语言环境。

重新启动 Postgres 后,使用嵌入了我所在语言环境的新存档文件,一切又恢复正常。dpkg-reconfigure locales只需再次运行删除我的语言环境即可轻松重现此问题,无需重新启动 Postgres,它就会继续工作。重新启动后,它会再次失败,直到语言环境再次添加到存档文件中。

不使用 localedef?

因此,看来最终使结果localedef存活下来的正确方法是不要手动使用,而是在文件中定义所需的语言环境,在最坏的情况下重新启动系统。dpkg-reconfigure localeslocaledef/usr/local/share/i18n/SUPPORTED

相关内容