如何在脚本内强制执行 shell 脚本字符编码

如何在脚本内强制执行 shell 脚本字符编码

我有一些内部包含 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_CTYPELC_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,而与定义时的值无关。

相关内容