Я пытаюсь портировать сценарий оболочки на гораздо более читаемую версию Python. Оригинальный сценарий оболочки запускает несколько процессов (утилиты, мониторы и т. Д.) В фоновом режиме с «&». Как я могу добиться того же эффекта в Python? Я бы хотел, чтобы эти процессы не умирали после завершения сценариев Python. Я уверен, что это как-то связано с концепцией демона, но я не мог найти, как это легко сделать.
295
subprocess.Popen()
это новый рекомендуемый способ с 2010 года (сейчас 2015 год) и (3) дублирующий вопрос, перенаправляющий сюда, также имеет принятый ответsubprocess.Popen()
. Приветствия :-)subprocess.Popen("<command>")
с файлом <command> во главе с подходящим шебангом. Идеально подходит для меня (Debian) со скриптами bash и python, косвенноshell
s и выживает в родительском процессе.stdout
идет к тому же терминалу, что и родительский. Так что это работает так же, как&
в оболочке, которая была запросом OP. Но, черт возьми, все вопросы прорабатываются очень сложно, в то время как небольшое тестирование показало это вОтветы:
Примечание . Этот ответ является менее актуальным, чем тот, который был опубликован в 2009 году.
subprocess
Теперь в документах рекомендуется использовать модуль, показанный в других ответах.Если вы хотите, чтобы ваш процесс запускался в фоновом режиме, вы можете либо использовать
system()
и вызывать его так же, как это делал ваш сценарий оболочки, либо вы можетеspawn
это сделать:(или, альтернативно, вы можете попробовать менее переносимый
os.P_NOWAIT
флаг).Смотрите документацию здесь .
источник
subprocess
подсказать нам, как отсоединить процессsubprocess
?В то время как решение jkp работает, более новый способ работы (и способ, рекомендуемый документацией) состоит в том, чтобы использовать
subprocess
модуль. Для простых команд это эквивалентно, но предлагает больше вариантов, если вы хотите сделать что-то сложное.Пример для вашего случая:
Это будет работать
rm -r some.file
в фоновом режиме. Обратите внимание, что вызов.communicate()
объекта, возвращаемого из,Popen
будет блокироваться до его завершения, поэтому не делайте этого, если хотите, чтобы он работал в фоновом режиме:Смотрите документацию здесь .
Кроме того, пояснение: «Фон», как вы его здесь используете, является чисто концепцией оболочки; технически, вы имеете в виду, что хотите запустить процесс без блокировки, пока вы ждете его завершения. Тем не менее, я использовал здесь «background» для обозначения поведения, похожего на shell-background.
источник
Popen()
чтобы избежать блокировки основного потока, и если вам нужен демон, посмотрите наpython-daemon
пакет, чтобы понять, как должен вести себя четко определенный демон. Ваш ответ в порядке, если вы удалите все, начиная с «Но будьте осторожны», за исключением ссылки на документы подпроцесса.Вы, вероятно, хотите получить ответ на вопрос «Как вызвать внешнюю команду в Python» .
Самый простой подход - использовать
os.system
функцию, например:По сути, все, что вы передадите в
system
функцию, будет выполнено так же, как если бы вы передали ее оболочке в скрипте.источник
Я нашел это здесь :
В windows (win xp) родительский процесс не завершится, пока
longtask.py
не завершит свою работу. Это не то, что вы хотите в CGI-скрипте. Проблема не является специфичной для Python, в сообществе PHP проблемы одинаковы.Решение состоит в том, чтобы передать
DETACHED_PROCESS
флаг создания процесса основнойCreateProcess
функции в Win API. Если вы установили pywin32, вы можете импортировать флаг из модуля win32process, в противном случае вы должны определить его самостоятельно:источник
Используйте
subprocess.Popen()
сclose_fds=True
параметром, который позволит отделить порожденный подпроцесс от самого процесса Python и продолжить работу даже после выхода из Python.https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f
источник
Возможно, вы захотите начать изучение модуля os для разветвления различных потоков (открыв интерактивный сеанс и выполнив справку (os)). Соответствующими функциями являются fork и любые из исполняемых. Чтобы дать вам представление о том, как начать, поместите что-то подобное в функцию, выполняющую разветвление (функция должна принимать список или кортеж 'args' в качестве аргумента, который содержит имя программы и ее параметры; вы также можете захотеть определить stdin, out и err для нового потока):
источник
os.fork()
действительно полезен, но имеет существенный недостаток - он доступен только в * nix.threading
: stackoverflow.com/a/53751896/895245 Я думаю, что это может работать на Windows.И захватывать вывод и работать на фоне с
threading
Как уже упоминалось в этом ответе , если вы фиксируете вывод с помощью,
stdout=
а затем пытаетесьread()
, то процесс блокируется.Однако есть случаи, когда вам это нужно. Например, я хотел запустить два процесса, которые общаются через порт между ними , и сохранить их стандартный вывод в файл журнала и стандартный вывод.
threading
Модуль позволяет нам сделать это.Во-первых, посмотрите, как выполнить часть перенаправления вывода в этом вопросе: Python Popen: одновременная запись в стандартный вывод и файл журнала
Затем:
main.py
sleep.py
После запуска:
stdout обновляется каждые 0,5 секунды для каждых двух строк:
и каждый файл журнала содержит соответствующий журнал для данного процесса.
Вдохновленный: https://eli.thegreenplace.net/2017/interacting-with-a-long-running-child-process-in-python/
Протестировано на Ubuntu 18.04, Python 3.6.7.
источник