Linux

如何使“localedef”的結果在“dpkg-reconfigure locales”中存在?

  • February 26, 2019

我使用的是 UB 16.04 LTS 伺服器,昨天發布並安裝了新版本的locales -package:

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-package 之後,我手動添加的一個被自動刪除,並且訪問依賴於該語言環境的數據庫失敗:

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時,創建的語言環境 usinglocaledef會從文件夾中刪除,/usr/lib/locale/de_DE.CP1252並且 Postgres 再次失敗。即使locale -a列印我的語言環境等。因此,這很可能是安裝新locales軟體包時/之後發生的情況。如果我localedef再次像上面記錄的那樣手動執行,Postgres 立即允許再次訪問舊數據庫。

我認識到的一件有趣的事情C.UTF-8是可用的語言環境,/usr/lib/locale就像我的自定義語言環境一樣,但由於某種原因永遠不會被自動刪除。在 Web 中搜尋該語言環境,它似乎是作為某個包的一部分由發行版提供,而不是根據需要在本地配置和生成:

我們現在有一個“不可安裝的”C.UTF-8 語言環境,即使您刪除了 locale-archive,或者更改了為 locale-archive 設置的已安裝語言,它仍然可用。

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-results 存活下來dpkg-reconfigure locales,或者在安裝新的locales-packages期間做了什麼?

謝謝!

這裡有不同的事情需要注意:

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/支持

該文件實際上是使我的語言環境可用的正確方法以及我添加它的方式是正確的。該行de_DE.CP1252 CP1252導致使用dpkg-reconfigure localeslike usinglocaledef手動創建相同的語言環境。唯一的區別是,在第一種情況下,語言環境被添加到文件/usr/lib/locale/locale-archive中,而後者創建單獨的目錄。這種差異導致了以下問題……

Postgres 無法辨識更改

我只是在執行後的測試期間從未重新啟動過 Postgres dpkg-reconfigure locales,這是必要的!

當使用localedefwhere 刪除或添加創建單個目錄時,Postgres 會立即辨識出使用該語言環境的數據庫會話。這就是為什麼我認為總是根據需要讀取語言環境,但似乎並非如此。相反,我猜存檔文件每個程序只打開一次,並且只有在其中找不到某些語言環境時,才會辨識其他目錄並按需辨識。因此,當存檔文件被刪除並新創建時,Postgres 根本無法辨識並且仍然使用舊內容,這些內容不包含我的語言環境。

在重新啟動使用嵌入了我的語言環境的新存檔文件的 Postgres 之後,一切又恢復了。這可以通過再次執行以刪除我的語言環境來輕鬆複製,dpkg-reconfigure locales並且無需重新啟動 Postgres,它只會繼續工作。重新啟動後,它再次失敗,直到語言環境再次添加到存檔文件中。

不使用localedef?

localedef因此,最終獲得生存結果的正確方法似乎dpkg-reconfigure locales是不要localedef手動使用,而是在文件中定義所需的語言環境,/usr/local/share/i18n/SUPPORTED並在最壞的情況下重新啟動系統。

引用自:https://serverfault.com/questions/955588