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 $C
或 cat 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'
我在 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 $C
或 cat 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'