l0b0 Asked: 2023-09-28 18:26:20 +0800 CST2023-09-28 18:26:20 +0800 CST 2023-09-28 18:26:20 +0800 CST 如何在 Bash 中获取 LC_CTYPE 等的当前值? 772 基本上,如何在 Bash 中实现这一点?解析locale- declare "$(locale | grep ^LC_CTYPE | tr --delete '"')"- 的输出似乎很糟糕,因为它涉及四个单独的命令。请记住,仅仅因为locale打印大多数或所有变量的值并不意味着这些变量实际上已设置!例如,在我的机器上locale打印LC_CTYPE="en_NZ.UTF-8"(以及其他行),但echo "$LC_CTYPE"什么也不打印。 bash 4 个回答 Voted Kusalananda 2023-09-28T21:24:56+08:002023-09-28T21:24:56+08:00 假设评估 的输出locale是安全的(我们假设locale不是 shell 函数、别名或其他非标准实用程序): (eval "$(locale)" && printf '%s\n' "$LC_CTYPE") 这会设置子 shell 环境中的所有LC_相关变量并输出变量的值LC_CTYPE。在子 shell 内部执行eval可以避免变量污染父环境LC_。 在我的 OpenBSD 系统上运行的示例,我只设置过LANG=C.UTF-8: $ (eval "$(locale)" && printf '%s\n' "$LC_CTYPE") C.UTF-8 如果您想将变量设置(并导出)LC_CTYPE为报告的值locale而不设置其他变量: $ export LC_CTYPE="$(eval "$(locale)" && printf '%s\n' "$LC_CTYPE")" $ printf '%s\n' "$LC_CTYPE" C.UTF-8 Best Answer don_crissti 2023-09-29T01:50:33+08:002023-09-29T01:50:33+08:00 根据 man 的说法,用双引号括起来的locale值表示它是一个“隐含值”:LC_CTYPE 环境中设置的变量值打印时不带 双引号,隐含值打印时带双引号。 这意味着LC_CTYPE未设置,locale并将打印“隐含”值,如果我理解正确,该值将是 的值LC_ALL,或者,如果也没有设置,则为 的值LANG: 对于 glibc,首先(无论类别如何)检查环境变量 LC_ALL,接下来检查与类别同名的环境变量,最后检查环境变量 LANG。使用第一个现有环境变量 因此,locale将使用它找到的第一个值,按以下顺序:LC_ALL,然后LC_CTYPE然后 然后LANG 请注意,LC_ALL如果设置了,则优先,因此即使也LC_CTYPE设置了(可能到不同的区域设置)也会报告forlocale的值。LC_ALLLC_CTYPE 总之,要获取LC_CTYPE当前正在使用的值locale,您可以运行类似的命令 echo ${LC_ALL:-${LC_CTYPE:-$LANG}} 最初我以为目标是获取LC_CTYPEif set 的实际值,并且只有在未设置时才回退到locale使用的内容,在这种情况下,必须交换前两个变量: echo ${LC_CTYPE:-${LC_ALL:-$LANG}} terdon 2023-09-28T21:09:41+08:002023-09-28T21:09:41+08:00 如果您只想解析输出locale然后设置变量,您可以像这样直接获取它: . <(locale | grep '^LC_CTYPE=') 仅选择该LC_TYPE行: $ locale | grep '^LC_CTYPE=' LC_CTYPE="en_US.UTF-8" 然后使用.内置命令将其获取到当前 shell 中: $ echo $LC_CTYPE $ . <(locale | grep '^LC_CTYPE=') $ echo "$LC_CTYPE" en_US.UTF-8 请注意,这需要一个支持进程替换的shell ,例如bashor zshorksh等。如果您不使用这样的外壳,您可能需要做一些更复杂的事情,例如 locale | grep '^LC_CTYPE=' > file && . ./file qqqq 2023-09-28T21:09:14+08:002023-09-28T21:09:14+08:00 不使用任何外部命令,除了locale: while read -r line; do [[ "${line}" =~ ^LC_CTYPE= ]] && { export LC_CTYPE="${line#*=}" break } done < <(locale)
假设评估 的输出
locale
是安全的(我们假设locale
不是 shell 函数、别名或其他非标准实用程序):这会设置子 shell 环境中的所有
LC_
相关变量并输出变量的值LC_CTYPE
。在子 shell 内部执行eval
可以避免变量污染父环境LC_
。在我的 OpenBSD 系统上运行的示例,我只设置过
LANG=C.UTF-8
:如果您想将变量设置(并导出)
LC_CTYPE
为报告的值locale
而不设置其他变量:根据 man 的说法,用双引号括起来的
locale
值表示它是一个“隐含值”:LC_CTYPE
这意味着
LC_CTYPE
未设置,locale
并将打印“隐含”值,如果我理解正确,该值将是 的值LC_ALL
,或者,如果也没有设置,则为 的值LANG
:因此,
locale
将使用它找到的第一个值,按以下顺序:LC_ALL
,然后LC_CTYPE
然后 然后LANG
请注意,LC_ALL
如果设置了,则优先,因此即使也LC_CTYPE
设置了(可能到不同的区域设置)也会报告forlocale
的值。LC_ALL
LC_CTYPE
总之,要获取
LC_CTYPE
当前正在使用的值locale
,您可以运行类似的命令最初我以为目标是获取
LC_CTYPE
if set 的实际值,并且只有在未设置时才回退到locale
使用的内容,在这种情况下,必须交换前两个变量:如果您只想解析输出
locale
然后设置变量,您可以像这样直接获取它:仅选择该
LC_TYPE
行:然后使用
.
内置命令将其获取到当前 shell 中:请注意,这需要一个支持进程替换的shell ,例如
bash
orzsh
orksh
等。如果您不使用这样的外壳,您可能需要做一些更复杂的事情,例如不使用任何外部命令,除了
locale
: