В Windows, как я могу защитить аргументы сценариев оболочки, используя подпроцесс Python 2.7? - PullRequest
3 голосов
/ 11 февраля 2011

Рассмотрим, например, следующий код Python:

subprocess.call([r'.\tst.bat', '"1|2"'])

Здесь я поместил двойные кавычки вокруг аргумента tst.bat, чтобы защитить '|'из оболочки, так как в конечном итоге tst.bat будет запускаться через оболочку Windows.Однако, если в аргументах есть двойные кавычки, подпроцесс в Python 2.7 избегает их.В результате tst.bat получает этот аргумент: \ "1 | 2 \".

Как я могу избежать аргумента "1 | 2", чтобы он был передан без преобразования в tst.bat?

Ответы [ 2 ]

1 голос
/ 04 августа 2013

Модуль подпроцесса в Windows в случае списка аргументов, переданных методу call , преобразует этот список в строку с помощью функции list2cmdline.В строке документации этой функции можно прочитать:

3) Двойная кавычка, которой предшествует обратная косая черта, интерпретируется как буквальная двойная кавычка.

В соответствии с этимрешение вашей проблемы должно выглядеть следующим образом

subprocess.call([r'.\tst.bat', r'\"1|2\"'])

Однако кажется, что существует несоответствие между документацией и реализацией функции list2cmdline;

Python 2.7.4 (default, Apr  6 2013, 19:55:15) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> print subprocess.list2cmdline([r'\"1|2\"'])
\\\"1|2\\\"

Такое же поведение в Python3.3.1.Я поднял ошибку в http://bugs.python.org/issue18649

ОБНОВЛЕНИЕ

Оказывается, меня смутила очень вводящая в заблуждение строка документации функции list2cmdline - см. http://bugs.python.org/issue18649для подробностей.

Последовательность аргументов, передаваемая в subprocess.call, переводится функцией list2cmdline, которая касается только механизма цитирования, используемого в среде выполнения MS C, а не механизма цитирования, используемого cmd.exe.Это делает передачу аргументов - которые позже будут интерпретированы cmd.exe - в subprocess.call как список, либо очень неловко, либо невозможно.

Однако в этом случае есть еще один шанс заставить его работать.list2cmdline двойные кавычки каждый аргумент с пробелом или табуляцией внутри.Если наличие пробела в конце вашего аргумента не нарушает пакетный файл, вы можете добавить его в конце, вызывая двойные кавычки, как вы хотели.

>>> import subprocess
>>> print subprocess.list2cmdline(['1|2 '])
"1|2 "
0 голосов
/ 11 февраля 2011

Эта (или похожая проблема) была зарегистрирована как ошибка.

Ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...