我有可以在bash中执行命令的基本代码。但是,使用unicode字符串时,所有内容在Windows上都会崩溃。这是一个测试示例:
cd /tmp
cat <<EOF > test.py
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import sys
from subprocess import Popen, PIPE
ON_POSIX = 'posix' in sys.builtin_module_names
def execute_bash(cmd):
command = ["bash", "-c", cmd]
p = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE,
close_fds=ON_POSIX, universal_newlines=False)
return p.communicate()
print(repr(execute_bash('echo hello'))) ## works fine
print(repr(execute_bash('echo à'))) ## fails
EOF
python test.py
我希望获得此输出(适用于linux):
(b'hello\n', b'')
(b'\xc3\xa0\n', b'')
但是有:
('hello\n', '')
('', "bash: $'echo \\303\\203\\302\\240': command not found\n")
所以我的问题是:
execute_bash
的实现?关于我已经研究过的内容以及解决该问题可能缺少的内容,这里还有一些背景知识:
我正在使用python 3.7
,并且知道一些窗口和编码方面的问题,我试图将其排除在本示例之外。
我知道自Popen
起,CPython的CreateProcessW(..)
实现使用python 3
,而且我们应该能够发送直接的unicode命令行。
我还知道subprocess.list2cmdline(..)
的存在将使一个unicode字符串中的args变平以馈入CreateProcessW(..)
。我有点意识到在Windows世界中应该对应用程序进行命令行解析...但是,这是我的知识受到限制的地方:哪个应用程序获取完整的命令行字符串?为什么它不能正确处理unicode字符串?
请注意,在cmd.exe
命令行上执行时,我们有同样的问题。
T:\>bash -c "echo hello"
hello
T:\>bash -c "echo à"
bash: $'echo \303\240': command not found
旁注:\303\240
对于à
的utf-8编码是八进制的。