![如何在脚本内强制执行 shell 脚本字符编码](https://linux22.com/image/79804/%E5%A6%82%E4%BD%95%E5%9C%A8%E8%84%9A%E6%9C%AC%E5%86%85%E5%BC%BA%E5%88%B6%E6%89%A7%E8%A1%8C%20shell%20%E8%84%9A%E6%9C%AC%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81.png)
我有一些内部包含 UTF8 编码字符的 shell 脚本,我想确保无论计算机区域设置如何,它们都能正确解码。
是否可以强制 shell(bash 或 sh)检测正确的脚本编码? (类似于 python 或 ruby 编码 cookie)
解决方案可能是一个自定义的 shebang,例如:
#!/bin/bash --utf8
该解决方案应该旨在更好的可移植性,因此没有必要坚持使用 bash。
编辑:也许我已经找到了使用递归脚本调用的可能解决方案:
# check if current locale is UTF8-based (otherwise this script may not work correctly)
locale | grep -q 'UTF-8'
if [ $? -ne 0 ]; then
export LC_ALL=en_GB.UTF-8
# recursive call this script with the modified environment
$0 "$@"
exit $?
fi
答案1
Bash 将字符串存储为字节字符串,并根据当前LC_CTYPE
设置执行操作。因此无需重新启动 bash:只需将LC_CTYPE
或LC_ALL
变量设置为您所需的区域设置即可。请注意,如果将字符串存储在变量或函数中,重要的是扩展变量或执行函数中的相关命令时的编码。这是一个演示这一点的脚本:
#!/bin/bash
LC_CTYPE=en_US.utf8
v_utf8='é'
n_utf8=${#v_utf8}
f_utf8 () { tmp='é'; echo ${#tmp}; }
echo "UTF-8 in UTF-8: $n_utf8 $(f_utf8)"
LC_CTYPE=en_US
v_latin1='é'
n_latin1=${#v_latin1}
f_latin1 () { tmp='é'; echo ${#tmp}; }
echo "Latin 1 in Latin 1: $n_latin1 $(f_latin1)"
echo "UTF-8 in Latin 1: ${#v_utf8} $(f_utf8)"
LC_CTYPE=en_US.utf8
echo "Latin 1 in UTF-8: ${#v_latin1} $(f_latin1)"
输出:
UTF-8 in UTF-8: 1 1
Latin 1 in Latin 1: 2 2
UTF-8 in Latin 1: 2 2
Latin 1 in UTF-8: 1 1
正如您所看到的,字符串的长度是根据 的当前值计算的LC_CTYPE
,而与定义时的值无关。