bash 变量中的汉字与文件中的汉字处理方式不同

Chinese characters in bash variable are handled differently than in file

我在 curl 输出中接收中文字符,然后将它们作为输入提供给 Python 脚本,但根据我处理字符的方式,我得到两种截然不同的行为。

我更喜欢的方法是给我一个 UnicodeEncodeError。

首选方法:

read -r C < <(curl ...)
python3 -c "import sys, urllib.parse; \
            urllib.parse.quote(sys.argv[1])" "$C"
# UnicodeEncodeError: 'utf-8' codec can't encode character '\udce5' in position 0: surrogates not allowed

替代方法:

curl ... > tmp.txt
python3 -c "import urllib.parse; \
            with open('tmp.txt', encoding='utf-8') as f: \
                print(urllib.parse.quote(f.read()))"
# Outputs %E5%85%89%0A

我能做些什么来使使用 bash 变量的第一种方法起作用吗?当我 echo $Ccat tmp.txt 时,中文字符正确打印到我的终端。

当我在我的机器上 运行 locale 时,我得到:

LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

编辑 我的环境是面包丁(在 ChromeOS 上)。我的 bash 是 GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

设置您的语言环境

python 在解释 argv 时使用 LC_CTYPE。强制使用 UTF8 语言环境。

read -r C < <(curl ...)
LC_CTYPE='en_US.UTF8' python3 -c "import sys, urllib.parse; \
            print(urllib.parse.quote(sys.argv[1]))" "$C"

除了设置 LC_CTYPE,您可以只设置 LANG,这取决于您系统的其他部分是否不使用 LC_CTYPE

或者默认配置一个。

安装语言环境(如果需要)

如果命令 LC_CTYPE='en_US.UTF8' 导致错误,您可能没有安装 en_US.UTF8 语言环境(或您选择的任何语言环境)。

您可以查看 运行 locale -a 安装了哪些语言环境。要安装 'en_US.UTF8' 语言环境:

sudo locale-gen 'en_US'
sudo locale-gen 'en_US.UTF-8'