Вопрос-Ответ

Start a background process in Python

Запустить фоновый процесс на Python

Я пытаюсь перенести сценарий оболочки на гораздо более читаемую версию python. Исходный сценарий оболочки запускает несколько процессов (утилиты, мониторы и т.д.) В фоновом режиме с помощью "&". Как я могу добиться того же эффекта в python? Я бы хотел, чтобы эти процессы не прекращались после завершения работы скриптов Python. Я уверен, что это как-то связано с концепцией демона, но я не смог найти, как это легко сделать.

Переведено автоматически
Ответ 1

Хотя решение jkp работает, более новый способ выполнения задач (и способ, рекомендуемый документацией) заключается в использовании subprocess модуля. Для простых команд это эквивалентно, но предлагает больше возможностей, если вы хотите сделать что-то сложное.

Пример для вашего случая:

import subprocess
subprocess.Popen(["rm","-r","some.file"])

Это будет выполняться rm -r some.file в фоновом режиме. Обратите внимание, что вызов .communicate() объекта, возвращаемого из Popen, будет заблокирован до его завершения, поэтому не делайте этого, если вы хотите, чтобы он выполнялся в фоновом режиме.:

import subprocess
ls_output=subprocess.Popen(["sleep", "30"])
ls_output.communicate() # Will block for 30 seconds

Смотрите документацию здесь.

Кроме того, уточняющий момент: "Background", как вы используете его здесь, - это чисто концепция оболочки; технически вы имеете в виду, что вы хотите запустить процесс без блокировки, пока вы ждете его завершения. Однако здесь я использовал "background" для обозначения поведения, подобного shell-background.

Ответ 2

Примечание: Этот ответ менее актуален, чем был при публикации в 2009 году. Теперь рекомендуется использовать subprocess модуль, показанный в других ответах, в документах


(Обратите внимание, что модуль subprocess предоставляет более мощные средства для запуска новых процессов и получения их результатов; использование этого модуля предпочтительнее, чем использование этих функций.)



Если вы хотите, чтобы ваш процесс запускался в фоновом режиме, вы можете либо использовать system() и вызвать его тем же способом, что и ваш сценарий оболочки, либо вы можете spawn это:

import os
os.spawnl(os.P_DETACH, 'some_long_running_command')

(или, в качестве альтернативы, вы можете попробовать флаг less portable os.P_NOWAIT).

Смотрите документацию здесь.

Ответ 3

Вы, вероятно, хотите получить ответ на "Как вызвать внешнюю команду в Python".

Самый простой подход - использовать os.system функцию, например:

import os
os.system("some_command &")

В принципе, все, что вы передаете в system функцию, будет выполняться так же, как если бы вы передали это в оболочку в скрипте.

Ответ 4

Я нашел это здесь:

В Windows (win xp) родительский процесс не завершится, пока longtask.py не завершит свою работу. Это не то, что вы хотите в CGI-скрипте. Проблема не специфична для Python, в сообществе PHP проблемы те же.

Решение состоит в том, чтобы передать DETACHED_PROCESS флаг создания процесса базовой CreateProcess функции в win API. Если у вас установлен pywin32, вы можете импортировать флаг из модуля win32process, в противном случае вам следует определить его самостоятельно:

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen([sys.executable, "longtask.py"],
creationflags=DETACHED_PROCESS).pid
python