原有代码如下:
def run_silently(cmd: str) -> str:
"""返回系统命令的执行结果"""
with os.popen(cmd) as fp:
return fp.read().strip()
在ubuntu里执行,一点问题也没有,去到Windows就报错了
经试验:`print(run_silently('echo 拟好'))` 能正常运行, `print(run_silently('git log'))`则报错如下
$ python change_version.py
Traceback (most recent call last):
File "change_version.py", line 79, in <module>
main()
File "change_version.py", line 61, in main
print(run_silently('git log'))
File "change_version.py", line 31, in run_silently
return fp.read().strip()
UnicodeDecodeError: 'gbk' codec can't decode byte 0x92 in position 592: illegal multibyte sequence
原因:编码问题
解决:修改代码如下
def run_silently(cmd: str) -> str:
"""返回系统命令的执行结果"""
with os.popen(cmd) as fp:
bf = fp._stream.buffer.read()
try:
return bf.decode().strip()
except UnicodeDecodeError:
return bf.decode('gbk').strip()
==== Updated At: 2023-08-22
由于0xab和0xa0这两个字符用gbk和utf8解码时分别报错了,所以修改成如下(同时支持Python2/Python3):
# coding:utf8
import os
def run_silently(
cmd, # type: str
errors="ignore", # type: str
): # type: (...) -> str
"""返回系统命令的执行结果"""
with os.popen(cmd) as fp:
if not hasattr(fp, "_stream"): # Compare with python2
return fp.read().strip()
bf = fp._stream.buffer.read().strip()
try:
return bf.decode("utf8", errors)
except UnicodeDecodeError:
return bf.decode("gbk", errors)
# 测试:
#print(run_silently("echo {}".format(b"\xa0\xab" + u"您好".encode("utf8"))))
注:decode函数的errors参数默认时strict,会严格比对字符集,一般场景下用ignore就可以了