【问题标题】:Errors when trying to save command line output to a file尝试将命令行输出保存到文件时出错
【发布时间】:2014-08-09 11:23:02
【问题描述】:

我正在运行一个 python 工具并试图将它的输出保存到一个文件中。如果我不将输出保存到文件中,则该工具运行得非常好。但是当我尝试将输出保存到文件时,它会引发以下错误并中断程序:

  File "./androdiff.py", line 118, in <module>
main(options, arguments)
  File "./androdiff.py", line 94, in main
ddm.show()
  File "./elsim/elsim/elsim_dalvik.py", line 772, in show
self.eld.show()
  File "./elsim/elsim/elsim.py", line 435, in show
i.show()
  File "./elsim/elsim/elsim_dalvik.py", line 688, in show
  print hex(self.bb.bb.start + self.offset), self.pos_instruction, self.ins.get_name(), self.ins.show_buff( self.bb.bb.start + self.offset )
  UnicodeEncodeError: 'ascii' codec can't encode character u'\u0111' in position 35: ordinal not in range(128)

我试过command |lesscommand &gt; outputcommand | tee output,都会抛出这样的错误。

请帮助解决问题。

谢谢!

【问题讨论】:

  • 当你“保存到文件”时,你是在重定向stdout吗?像这样python app.py &gt; file ?
  • 是的。我就是这么用的

标签: python linux unicode command-line pipe


【解决方案1】:

如果 stdout 字符编码无法自动确定,例如,当输出重定向到文件时,请显式设置 PYTHONIOENCODING 环境变量:

$ PYTHONIOENCODING=utf-8 python app.py > file

如果输出可能会发送到终端,请不要在脚本中对字符编码进行硬编码;而是打印 Unicode 字符串,让用户配置他们的环境。

【讨论】:

  • 这就是我所需要的——终端输出正常,对于小输出,我可以正确地复制粘贴它。变量名不是很方便,但它可以节省一天的时间。我需要检查一下,这是否适用于os.environ。好的 - 确实如此。
【解决方案2】:

您需要在打印之前指定字符串的编码:

print unicode(hex(self.bb.bb.start + self.offset)).encode('utf-8')
print unicode(self.pos_instruction, self.ins.get_name()).encode('utf-8')
print unicode(self.ins.show_buff( self.bb.bb.start + self.offset )).encode('utf-8')

之所以可行,是因为 python 在打印到终端时会自动正确编码您的字符串(在您的情况下为 utf-8)(它检测到终端使用 utf-8)。

当您将输出重定向到文件时,Python 没有关于它应该使用什么编码的信息,而是默认为 ascii(这会导致您的错误)。

作为一般经验法则,请确保在打印之前始终对字符串进行编码,以使 print 在所有环境中都能正常工作。

最好的方法可能是为此定义自己的打印方法:

def myprint(unicodestr): 
    print unicodestr.encode('utf-8')

如果您想避免上述情况并使用 utf-8 编码默认打印,您可以这样做

import sys
import codecs
sys.stdout=codecs.getwriter('utf-8')(sys.stdout)

当心这种方法!一些第三方库可能依赖于 ascii 和 break 的默认编码。请注意,这整个混乱已经在 Python 3 中得到解决(默认为 UTF-8 编码)

【讨论】:

  • 谢谢!马丁。我可以将默认值从 ascii 更改为 utf-8,而不是更改 print 的每个调用吗?工具中有很多地方使用了print,我懒得去重构每一个。
  • 您不应在脚本中硬编码用户的终端字符编码。你可以使用PYTHONIOENCODING instead
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-01
  • 1970-01-01
  • 2016-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多