Arch-Linux

為什麼幾乎每個程序都在抱怨我的語言環境?

  • April 20, 2020

我正在使用 Arch Linux,並且我已經按照wiki上關於設置我的語言環境的說明進行操作。

幾乎每個執行的程序都會抱怨語言環境——甚至locale。它看起來像這樣:

% locale
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=
LC_CTYPE=en_US.UTF-8
LC_NUMERIC=en-US
LC_TIME=en-US
LC_COLLATE="POSIX"
LC_MONETARY=en-US
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT=en-US
LC_IDENTIFICATION="POSIX"
LC_ALL=

要麼:

% perl
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
   LANGUAGE = (unset),
   LC_ALL = (unset),
   LC_TIME = "en-US",
   LC_NUMERIC = "en-US",
   LC_MONETARY = "en-US",
   LC_MEASUREMENT = "en-US",
   LC_CTYPE = "en_US.UTF-8",
   LANG = (unset)
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C")

有點令人困惑的是,/etc/locale.gen有幾個例子;所有 UTF-8 行都有“something.UTF-8”,並且正在執行時locale-gen顯示en_US.UTF-8... done,但是locale -a,它應該向您顯示可用的語言環境顯示en_US.utf8/etc/locale-gen我已經嘗試過 in和LOCALE=in兩種格式的各種組合/etc/rc.conf,但沒有解決問題。

附加資訊:

% locale -a
C
POSIX
en_US
en_US.iso88591
en_US.utf8

Bruce Ediger 的設置LANG=CLC_ALL=en_US.UTF-8工作建議(實際上,設置LC_ALL修復了它,設置LANG無關緊要),但我想知道發生了什麼。根據SUS, LC_ALL 將覆蓋所有其他 LC_* 變數,如果它已設置且不為空。在我的系統中,它是設置的,但它是空的,所以應該忽略它,而應該使用其他值。這不是正在發生的事情,似乎應用程序正在呼叫setlocaleLC_ALL得到NULL返回並生成錯誤,即使其他呼叫setlocale返回一個好的字元串也是如此。

這是頂部的ltracelocale向右滾動查看函式返回值)

% ltrace locale
(0, 0, 0, -1, 0x7f5c1ae44510)                                                                      = 0x7f5c1ae47140
__libc_start_main(0x401d70, 1, 0x7fff7c8cfbf8, 0x404610, 0x4046a0 <unfinished ...>
setlocale(0, "")                                                                                   = "en_US.UTF-8"
setlocale(5, "")                                                                                   = "en_US.UTF-8"
textdomain("libc")                                                                                 = "libc"
argp_parse(0x607280, 1, 0x7fff7c8cfbf8, 0, 0x7fff7c8cfad4)                                         = 0
setlocale(6, "")                                                                                   = NULL
dcgettext(0, 0x405aa8, 5, 0, 0)                                                                    = 0x405aa8
error(0, 2, 0x405aa8, 1, 0locale: Cannot set LC_ALL to default locale: No such file or directory)  

您缺少一個文件,該文件將用於在沒有設置$LANG$LC_ALL(或所有更具體的$LC_whatever)設置的情況下預設語言環境。

在較舊的 glibc 上,它是/usr/lib/locale/locale-archive. 因為 GNU/Linux 是混亂的,你應該使用 strace 來確定在你的機器上使用的特定版本中需要哪些文件:

strace -e 文件區域設置
execve("/usr/bin/locale", ["locale"], [/* 36 vars */]) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (沒有這樣的文件或目錄)
打開(“/etc/ld.so.cache”,O_RDONLY)= 3
打開(“/lib/libc.so.6”,O_RDONLY)= 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3

———————- 1天后添加的評論:

ltrace -S應該沒問題,因為它顯示系統呼叫。

否則,“ltrace”不是很有幫助(即它與 相比適得其反strace),因為它只顯示最上面的呼叫。這些是顯而易見的 ( setlocale(3)),而真正的問題發生在libc.

聽起來您已經安裝了原始語言環境數據,因為en_US.UTF-8工作正常。

如果是這樣,那麼這樣的事情應該可以解決您的問題,設置系統範圍的預設值:

localedef -f UTF-8 -i en_US en_US.UTF-8

引用自:https://unix.stackexchange.com/questions/43054