ほとんどすべてのプログラムが私のロケールについて文句を言うのはなぜですか?

ほとんどすべてのプログラムが私のロケールについて文句を言うのはなぜですか?

私はArch Linuxを使用しており、フォローしました。ウィキペディア私のロケール設定について。

実行しているほとんどすべてのプログラムはロケールについて文句を言います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行には、locale-gen実行時に表示される「something.UTF-8」がありますが、使用可能なロケールを表示する必要があります。 inとinの形式のさまざまな組み合わせを試しましたが、問題は解決されませんでした。en_US.UTF-8... donelocale -aen_US.utf8/etc/locale-genLOCALE=/etc/rc.conf

追加情報:

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

Bruce Edigerの設定提案はうまくLANG=CいきましたがLC_ALL=en_US.UTF-8(実際の設定でLC_ALL問題が解決されたので設定はLANG問題ありません)、何が起こっているのか知りたいです。 ~によるとステンレス鋼、LC_ALLが設定されていて空でない場合、LC_ALLは他のすべてのLC_ *変数をオーバーライドします。私のシステムには設定されていますが空であるため、無視して別の値を使用する必要があります。これは本当ではありません。他の呼び出しが良い文字列を返しても、アプリケーションが呼び出して戻り値を取得してエラーを生成するsetlocaleようLC_ALLです。NULLsetlocale

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)  

ベストアンサー1

欠落しているときに使用するファイルがありません($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 (該当するファイルやディレクトリなし)
open("/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システムコールを表示するので大丈夫です。

straceそれ以外の場合、「ltrace」は親呼び出しのみを表示するため、あまり役に立ちません(つまり、それと比較して非生産的です)。これらは明らかである( setlocale(3))。ここで本当の問題が発生しますlibc

お持ちのようです生のロケールデータをインストールするとen_US.UTF-8機能します。

その場合は、次のようにシステム全体のデフォルト値を設定して問題を解決する必要があります。

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

おすすめ記事