Разница между subprocess.Popen и os.system

Ответы:

100

Если вы ознакомитесь с разделом подпроцессов документации Python , вы заметите, что есть пример того, как заменить os.system()на subprocess.Popen():

sts = os.system("mycmd" + " myarg")

... делает то же самое, что и ...

sts = Popen("mycmd" + " myarg", shell=True).wait()

«Улучшенный» код выглядит более сложным, но он лучше, потому что, если вы знаете subprocess.Popen(), вам больше ничего не нужно. subprocess.Popen()заменяет несколько других инструментов ( os.system()это только один из тех), которые были разбросаны по трем другим модулям Python.

Если это поможет, считайте, что subprocess.Popen()это очень гибкий os.system().

Джейкоб Марбл
источник
Вы также можете использовать sts = p.wait()вместо последней строки.
Sven Marnach
1
@JacobMarble, так что предположим, что я вызываю скрипт очистки селена из другого скрипта Python, который из них позволит мне завершить скрипт очистки, а затем и только потом выполнить следующую строку кода? То есть мой очистка должна завершиться, прежде чем выполнение может продолжиться.
Пракхар Мохан Шривастава
Возможно, также упомяните stackoverflow.com/questions/3172470/…, чтобы указать, что вам следует избегать, shell=Trueесли вы можете. Наличие этой опции - одно из преимуществ subprocess.Popen()и вспомогательных функций.
Tripleee
@PrakharMohanSrivastava Если вы хотите заблокировать поток и дождаться, пока команда завершит свою работу, проверьте: stackoverflow.com/a/2837319/5252192
AmirHossein 01
@PrakharMohanSrivastava, в общем и целом, os.systemи subprocess.call/popen/runблокируют / ждут завершения команды: stackoverflow.com/a/14059648/4752883
alpha_989
47

subprocess.Popen()строгий супер-набор os.system().

Ян Худек
источник
10
Это полный элегантный ответ.
Farsheed
23

os.systemэквивалентен systemкоманде Unix , а subprocessбыл вспомогательным модулем, созданным для обеспечения многих возможностей, предоставляемых Popenкомандами, с более простым и управляемым интерфейсом. Они были разработаны аналогично команде Unix Popen .

system()выполняет команду, указанную в command, путем вызова /bin/sh -c commandи возвращается после завершения команды

В то время как:

popen()Функция открывает процесс создания канала, разветвление, и вызова оболочки.

Если вы думаете, какой из них использовать, subprocessопределенно используйте, потому что у вас есть все возможности для выполнения, а также дополнительный контроль над процессом.

Сентил Кумаран
источник
хорошо .. тогда есть ли способ, которым я могу выполнить как os.system, так и открыть в Windows env? Я новичок и мне нужно копать глубже ..
Arovit
Да, вы можете использовать как os.system, так и подпроцесс в среде Windows. Взгляните на базовые руководства на effbot.org (онлайн-книга стандартной библиотеки Python)
Сентил Кумаран,
Осторожно - если вы работаете в старых системах, модуль подпроцесса недоступен.
Стив Ханов
21

Подпроцесс основан на popen2 и, как таковой, имеет ряд преимуществ - здесь есть полный список в PEP , но некоторые из них:

  • используя трубу в оболочке
  • лучшая поддержка новой строки
  • лучшая обработка исключений
Энди Микула
источник
2

При запуске python (cpython) в Windows система <built-in function system> os.system будет выполняться под занавесками _wsystem, а если вы используете ОС, отличную от Windows, она будет использовать system .

Напротив, Popen должен использовать CreateProcess в Windows и _posixsubprocess.fork_exec в операционных системах на основе posix.

Тем не менее, важный совет исходит из документации os.system , в которой говорится:

Модуль подпроцесса предоставляет более мощные средства для создания новых процессов и получения их результатов; использование этого модуля предпочтительнее, чем использование этой функции. См. Раздел «Замена старых функций модулем подпроцесса» в документации по подпроцессам, где приведены некоторые полезные рецепты.

BPL
источник