2016-03-31 6 views
2

Мой вопрос более теоретический, чем практический, я нашел больше ответов, объясняющих , как, но не Почему следует использовать список в вызове subprocess.Popen.Почему мы должны использовать список в subprocess.Popen?

Например, как известно:

Python 2.7.10 (default, Oct 14 2015, 16:09:02) 
[GCC 5.2.1 20151010] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import subprocess 
>>> cmd = subprocess.Popen(["python", "-V"], stdout=subprocess.PIPE) 
Python 2.7.10 

Тогда я бездельничал в UNIX и нашел что-то интересное:

[email protected]:~$ strace -f python -V 2>&1 
execve("/usr/bin/python", ["python", "-V"], [/* 29 vars */]) = 0 

Возможно как execve и модель список, subprocess польза некоторым образом связаны между собой, но может ли кто-нибудь дать хорошее объяснение этому?

Заранее спасибо.

+1

Это удобно, с одной стороны.Когда у вас есть аргумент, который содержит пробел и два разных типа кавычек, требуется довольно немного, чтобы иметь возможность помещать его в строку таким образом, что Bash будет рассматривать ее как один аргумент. Когда он находится в списке, «Popen» позаботится об этом для вас. – zondo

+0

Как в стороне, вы обычно не должны использовать 'subprocess.Popen()' - в некоторых случаях он работает в некоторых случаях на некоторых платформах, но в общем случае он только * запускает * подпроцесс, и вам нужно несколько дополнительных взаимодействий для затем правильно запустить и завершить процесс. Обертки в библиотеке 'subprocess' позаботятся об этом и защищают вас от основных сложностей - только когда они неадекватны для ваших нужд, если вы перейдете к основным функциям рабочей лошади. В этом случае 'subprocess.call()' будет инструментом выбора. – tripleee

ответ

3

Подходящее представление уровня C представляет собой массив *char []. Представление этого как списка в Python - это очень естественное и прозрачное отображение.

Вы можете использовать строку вместо списка с shell=True; оболочка затем отвечает за разбор командной строки в массив * char []. Однако оболочка добавляет несколько неприятных сложностей; см. множество вопросов для why you want to avoid shell=True для подробного объяснения.

command line arguments argv and the environment envp - это всего лишь две из многих структур уровня ОС, которые по существу представляют собой массивы строк с нулевым символом.

3

A процесс - абстракция уровня ОС - для создания процесса вы должны использовать API OS, который определяет, что вы должны использовать. Нет необходимости использовать список, например, строка (lpCommandLine) - это собственный интерфейс on Windows (CreateProcess()). POSIX uses execv() и, следовательно, собственный интерфейс представляет собой последовательность аргументов (argv). Естественно, subprocess Модуль Python использует эти интерфейсы для запуска внешних команд (создания новых процессов).

Технический (неинтересный) ответ заключается в том, что в «почему мы должны», часть «не обязательно», как показывает Windows.

Чтобы понять «почему это является», вы можете попросить создателей CreateProcess(), execv() функций.

Чтобы понять «почему мы должны » использовать список, посмотрите на таблицу содержания для Unix (список) и Windows (в строки): How Command Line Parameters Are Parsed - задача, которая должна быть простой осложнено на Windows.

Главное отличие состоит в том, что на POSIX вызывающий абонент отвечает за разделение командной строки на отдельные параметры. В то время как на Windows сама команда анализирует свои параметры. Различные программы могут и используют разные алгоритмы для анализа параметров. subprocess module uses MS C runtime rules (subprocess.list2cmdline()), to combine args list into the command line. Программисту гораздо труднее понять, как параметры могут анализироваться в Windows.

 Смежные вопросы

  • Нет связанных вопросов^_^