macOS 中 Python 子进程标准输出中出现 0xc3 的 UnicodeDecodeError
UnicodeDecodeError with 0xc3 in Python subprocess stdout in macOS
我正在开发一个 python 脚本来在 WSL 和 macOS 中编译 LaTeX 文件,但是当我在 macOS 中 运行 它时,它在子进程 stdout utf-8 编解码器中失败。但是,它适用于 WSL。 Python 两个版本都是 3.6
代码没有任何code/decode句,所以我认为问题出在子进程stdout的内部调用
def execute(cmd, pipe):
if pipe:
ps = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output = subprocess.check_output(pipe, stdin=ps.stdout, universal_newlines=True)
print(colored(output, 'red'), file=sys.stderr)
ps.wait()
else:
output = subprocess.call(cmd)
print(colored(output, 'red'), file=sys.stderr)
start_time = time.time()
for cmd, pipe in zip(commands, pipes):
print(colored(cmd, 'green'), file=sys.stderr)
execute(cmd, pipe)
我得到的输出是
['pdflatex', '-shell-escape', '--interaction', 'nonstopmode', '-file-line-error', 'besolidary.tex']
Traceback (most recent call last):
File "compile.py", line 61, in <module>
execute(cmd, pipe)
File "compile.py", line 50, in execute
output = subprocess.check_output(pipe, stdin=ps.stdout, universal_newlines=True)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py", line 336, in check_output
**kwargs).stdout
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py", line 405, in run
stdout, stderr = process.communicate(input, timeout=timeout)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py", line 830, in communicate
stdout = self.stdout.read()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 1335: invalid continuation byte
在 WSL 中工作正常并抛出所有命令。
由于您指定了 universal_newlines=True
,Python 隐含地期望来自子进程的 text-output。由于没有给 check_output()
编码,它默认为 locale.getpreferredencoding(False)
返回的编码;这恰好是 utf-8
.
在你的例子中,子进程实际上并没有按照 Python 认为首选的编码方式对其输出进行编码,你在尝试这样做时会得到一个 DecodeError。
如果您确实希望从子进程获得 text-output,则需要一种方法来找出子进程将使用的编码(或强制其使用)。否则,如果输出实际上是二进制的,请将 universal_newlines
保留为默认值。
我正在开发一个 python 脚本来在 WSL 和 macOS 中编译 LaTeX 文件,但是当我在 macOS 中 运行 它时,它在子进程 stdout utf-8 编解码器中失败。但是,它适用于 WSL。 Python 两个版本都是 3.6
代码没有任何code/decode句,所以我认为问题出在子进程stdout的内部调用
def execute(cmd, pipe):
if pipe:
ps = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output = subprocess.check_output(pipe, stdin=ps.stdout, universal_newlines=True)
print(colored(output, 'red'), file=sys.stderr)
ps.wait()
else:
output = subprocess.call(cmd)
print(colored(output, 'red'), file=sys.stderr)
start_time = time.time()
for cmd, pipe in zip(commands, pipes):
print(colored(cmd, 'green'), file=sys.stderr)
execute(cmd, pipe)
我得到的输出是
['pdflatex', '-shell-escape', '--interaction', 'nonstopmode', '-file-line-error', 'besolidary.tex']
Traceback (most recent call last):
File "compile.py", line 61, in <module>
execute(cmd, pipe)
File "compile.py", line 50, in execute
output = subprocess.check_output(pipe, stdin=ps.stdout, universal_newlines=True)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py", line 336, in check_output
**kwargs).stdout
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py", line 405, in run
stdout, stderr = process.communicate(input, timeout=timeout)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py", line 830, in communicate
stdout = self.stdout.read()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 1335: invalid continuation byte
在 WSL 中工作正常并抛出所有命令。
由于您指定了 universal_newlines=True
,Python 隐含地期望来自子进程的 text-output。由于没有给 check_output()
编码,它默认为 locale.getpreferredencoding(False)
返回的编码;这恰好是 utf-8
.
在你的例子中,子进程实际上并没有按照 Python 认为首选的编码方式对其输出进行编码,你在尝试这样做时会得到一个 DecodeError。
如果您确实希望从子进程获得 text-output,则需要一种方法来找出子进程将使用的编码(或强制其使用)。否则,如果输出实际上是二进制的,请将 universal_newlines
保留为默认值。