尝试将命令行输出保存到文件时出错

1 投票
2 回答
784 浏览
提问于 2025-04-18 10:18

我在运行一个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 > outputcommand | tee output,结果都出现了同样的错误。

请帮我解决这个问题。

谢谢!

2 个回答

3

如果系统无法自动确定输出的字符编码,比如当输出被重定向到一个文件时,建议你明确设置一下 PYTHONIOENCODING 这个环境变量:

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

在你的脚本中不要死死地写死字符编码,特别是当输出可能会显示在终端上时;最好打印出Unicode字符串,让用户自己去配置他们的环境。

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,这样可能会导致问题。值得注意的是,这个麻烦在Python 3中已经解决了(它默认使用UTF-8编码)。

撰写回答