我使用以2.7(seafile-cli
,来自文件同步解决方案Seafile)编写的Python脚本。
我知道unicode is problematic in Python 2,但幸运的是,在启动脚本时正确处理了带有变音符号的文件名:
$ # seaf-cli status
# Name Status Progress
photos downloading 0/0, 0.0KB/s
Ma bibliothèque downloading 566/1770, 1745.7KB/s
videos downloading 28/1203, 5088.0KB/s
dev-perso downloading 0/0, 0.0KB/s
dev-pro downloading 0/0, 0.0KB/s
令我惊讶的是,在传递此输出时,Python脚本以UnicodeEncodeError
崩溃:
$ seaf-cli status | cat -
# Name Status Progress
photos downloading 0/0, 0.0KB/s
Traceback (most recent call last):
File "/usr/bin/seaf-cli", line 845, in <module>
main()
File "/usr/bin/seaf-cli", line 841, in main
args.func(args)
File "/usr/bin/seaf-cli", line 649, in seaf_status
tx_task.rate/1024.0)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe8' in position 11: ordinal not in range(128)
虽然我知道它最初可能与Ma bibliothèque
出现问题(但没有),但为什么管道传输会触发回溯?
那不是shell的问题吗? -输出此时已“离开”脚本。
编辑:answer在another question中。标记为重复。
答案 0 :(得分:0)
Python知道如何在程序内部处理编码,因为它使用了终端应用程序正在使用的任何编码。
发送(管道传输)输出时,需要对其进行编码。这是因为使用管道实际上在应用程序之间发送字节流。每个管道都是单向通道,一侧写入数据,另一侧读取数据。
使用管道或重定向,您正在将数据发送到fd,该数据由另一个应用程序读取。
因此,您需要确保Python在发送数据之前正确地对数据进行编码,然后输入程序需要在处理之前解码。
您也可能会发现此question有用
更新:我将尝试详细说明编码。我的答案的第一行是因为您的Python解释器使用特定的编码,所以它知道如何将六进制值(实际字节)转换为符号。
我的口译员没有;如果我尝试根据您的文本创建字符串-我会收到错误消息:
>>> s = 'bibliothèque'
Unsupported characters in input
这是因为我在解释器上使用了不同的编码。
您的外壳使用与Python解释器不同的编码。当Python从程序中发送数据时,它使用默认编码:ASCII。它无法使用ASCII转换您的特殊字符(由十六进制值\ xe8显示)。因此,您必须指定要使用哪种编码,以便Python发送。
如果更改外壳程序编码,您也许可以克服这一点-选中此question on SO。
PS -Ned Batchelder在youtube上有一段关于Unicode的精彩视频-也许这将为这个主题提供更多启示。