如何修复 openSUSE Linux 中的 UTF-8/区域设置问题(在终端/文件名和程序对话中)

Ned*_*d64 4 opensuse unicode locale

我有一些文件/文件夹名称不是 7 位干净的,并且它们在我的 openSUSE 系统中无法正确显示。

\n\n

文件夹 /music/Gabriel_Faur\xc3\xa9 的示例:

\n\n
# ls -1d /music/Gabriel_Faur?\n/music/Gabriel_Faur??\n
Run Code Online (Sandbox Code Playgroud)\n\n

也许区域设置LC_CTYPE未设置为某个 UTF-8 值?

\n\n
# locale\nlocale: Cannot set LC_ALL to default locale: No such file or directory\nLANG=en_US.UTF-8\nLC_CTYPE=en_US.UTF-8\nLC_NUMERIC=en_US.UTF-8\nLC_TIME=en_GB.UTF-8\nLC_COLLATE="en_US.UTF-8"\nLC_MONETARY=en_GB.UTF-8\nLC_MESSAGES=en_US.UTF-8\nLC_PAPER=a4\nLC_NAME=en_US.UTF-8\nLC_ADDRESS=en_US.UTF-8\nLC_TELEPHONE=en_US.UTF-8\nLC_MEASUREMENT=en_US.UTF-8\nLC_IDENTIFICATION=en_US.UTF-8\nLC_ALL=\n
Run Code Online (Sandbox Code Playgroud)\n\n

LC_CTYPE嗯,我认为这对于 Unicode 来说是件好事!错误消息说什么?

\n\n

有趣的是,设置LC_ALL为精确的值LC_CTYPE就可以了:

\n\n
# setenv LC_ALL en_US.UTF-8\n# ls -1d /music/Gabriel_Faur?\n/music/Gabriel_Faur\xc3\xa9\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,我不想将 LC_ALL 设置为 en_US.UTF-8 (或其他任何内容,真的),因为它会弄乱其他一些设置!这无法解决问题,但对我来说只是一个糟糕的解决方法。

\n\n

/bin/ls另外,为什么在将字符打印到屏幕时LC_CTYPE 被和/或我的 shell 忽略?

\n\n

在 Arch Linux 中,我会检查是否生成了语言环境,但在 openSUSE 中我没有找到任何关于该主题的信息。此外,该语言环境似乎确实存在。

\n\n

编辑:

\n\n
# ls -1d /music/Gabriel_Faur? | hexdump -C\n00000000  2f 6d 75 73 69 63 2f 47  61 62 72 69 65 6c 5f 46  |/music/Gabriel_F|\n00000010  61 75 72 c3 a9 0a                                 |aur...|\n00000016\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以它是正确的 UTF-8(据我所知)。

\n\n

编辑2:

\n\n
# locale -a | grep en_US\nen_US\nen_US.iso885915\nen_US.utf8\n# locale -a | wc -l\n495\n
Run Code Online (Sandbox Code Playgroud)\n\n

EDIT3(正确答案后):

\n\n
# unsetenv LC_PAPER\n# unsetenv LC_ALL\n# ls -1d /*/Gabriel_Faur?\n/music/Gabriel_Faur\xc3\xa9\n
Run Code Online (Sandbox Code Playgroud)\n\n

该变量可防止 UTF-8 编码的 Unicode 字符在屏幕上LC_PAPER=a4打印(无双关语)!

\n

Sté*_*las 5

locale: Cannot set LC_ALL to default locale: No such file or directory消息告诉您的是您尝试使用的区域设置之一不存在。它与环境变量无关$LC_ALL,只是在基于环境变量初始化本地化的调用返回 NULLlocale时报告错误,表明无法找到通过各种变量之一配置的区域设置。setlocale(LC_ALL, "")LC_*/LANG

在这里,由于它可以LC_ALL=en_US.UTF-8覆盖所有其他的,所以问题一定出在LC_PAPER=a4. a4不是系统上有效区域设置的名称,并且会导致setlocal(LC_ALL, "")失败。

失败时setlocale(),行为默认为 C 语言环境,其中字符编码为 ASCII。在 C 语言环境中,每个字节都是一个字符,但 0xc3 和 0xa9 是未知字符,因为它们不是 ASCII 格式,因此ls -q(并且-q在输出到达终端时启用)将它们呈现为?.

您可以使用以下命令查看系统上可用区域设置的列表:

locale -a
Run Code Online (Sandbox Code Playgroud)

你可能在那里找不到a4。如果您希望纸张尺寸为A4,则locale -k LC_PAPER输出:

height=297
width=210
paper-codeset="UTF-8"
Run Code Online (Sandbox Code Playgroud)

您可能想要使用欧洲语言环境$LC_PAPER,例如en_GB.UTF-8.