基本上就是如何实现这在巴什?解析locale
- -的输出declare "$(locale | grep ^LC_CTYPE | tr --delete '"')"
似乎很糟糕,因为它涉及四个单独的命令。请记住,仅仅因为locale
打印大多数或所有变量的值并不意味着这些变量实际上已设置!例如,在我的机器上locale
打印LC_CTYPE="en_NZ.UTF-8"
(以及其他行),但echo "$LC_CTYPE"
什么也不打印。
答案1
假设评估 的输出locale
是安全的(我们假设locale
不是 shell 函数、别名或其他非标准实用程序):
(eval "$(locale)" && printf '%s\n' "$LC_CTYPE")
这会设置LC_
子 shell 环境中的所有相关变量并输出变量的值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
答案2
据男子称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_ALL
LC_CTYPE
总之,要获取LC_CTYPE
当前正在使用的值,locale
您可以运行类似的命令
echo ${LC_ALL:-${LC_CTYPE:-$LANG}}
最初我以为目标是获取LC_CTYPE
if set 的实际值,并且只有在未设置时才回退到locale
使用的内容,在这种情况下,必须交换前两个变量:
echo ${LC_CTYPE:-${LC_ALL:-$LANG}}
答案3
如果您只想解析输出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流程替代,例如bash
或zsh
或ksh
以及其他。如果您不使用这样的 shell,您可能需要做一些更复杂的事情,例如
locale | grep '^LC_CTYPE=' > file && . ./file
答案4
不使用任何外部命令,除了locale
:
while read -r line; do
[[ "${line}" =~ ^LC_CTYPE= ]] && {
export LC_CTYPE="${line#*=}"
break
}
done < <(locale)