Надежный способ выполнения кода Unicode Bash с Python на Windows? - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть рабочий базовый код, который будет выполнять команды в bash.Но все падает на окнах при использовании Unicode-строк.Вот тестовый пример:

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, которая бы работала для любого кода в windows ?

Вот еще несколько сведений о том, чтоЯ уже изучил, и то, что мне, вероятно, не хватает для решения этой проблемы:

Я использую python 3.7, и я знаю несколько проблем с окнами и кодировками, которые я пытаюсь исключить из этого примера,Я знаю, что реализация CPython Popen использует CreateProcessW(..) начиная с python 3 и что мы должны иметь возможность отправлять прямые командные строки Unicode.Мне также известно о существовании subprocess.list2cmdline(..), которое сгладит аргументы в одну строку юникода для подачи в CreateProcessW(..).Я вроде знаю, что в мире Windows разбор командной строки должен обрабатываться приложением ... но вот где мои знания ограничены: какое приложение получает полную строку командной строки?почему не удается правильно обработать строку в юникоде?

Обратите внимание, что при выполнении в командной строке cmd.exe возникает та же проблема.

T:\>bash -c "echo hello"
hello
T:\>bash -c "echo à"
bash: $'echo \303\240': command not found

Примечание: \303\240 isвосьмеричное для кодировки utf-8 à.

...