Запустить скрипт python в фоне linux

Обновлено: 04.07.2024

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

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

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

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

(или, альтернативно, вы можете попробовать менее портативный os.P_NOWAIT флаг).

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

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

Это должно работать rm -r somefile на заднем плане. но будьте осторожны: subprocess.Popen() запускает процесс только в фоновом режиме, если ничего в скрипте python не зависит от вывода выполняемой команды:

например, следующая команда не запустить в фоновом режиме:

кроме того, точка разъяснения: "фон" чисто концепция оболочки: то, что вы, вероятно, хотите, чтобы породить новый процесс. Я использовал " фон " здесь, чтобы ссылаться на shell-background-подобное поведение, но не путайте это с процессом, фактически находящимся в фон.

самый простой подход-использовать

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

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

использовать subprocess.Popen() С close_fds=True параметр, который позволит порожденному подпроцессу быть отделенным от самого процесса Python и продолжать работать даже после выхода Python.

вы, вероятно, хотите начать исследовать модуль ОС для разветвления различных потоков (открыв интерактивный сеанс и выдав справку(os)). Соответствующими функциями являются fork и любой из exec. Чтобы дать вам представление о том, как начать, поместите что-то вроде этого в функцию, которая выполняет вилку (функция должна взять список или кортеж "args" в качестве аргумента, который содержит имя программы и ее параметры; вы также можете определить stdin, out и err для нового thread):

требуется запустить простенький python скрипт в background режиме для чего я в терминале ввожу ./name.py далее CTR+Z перевожу его ‘сворачиваю’ и когда требуется достаю с помощью bg. Проблема в том что я могу его ‘свернуть’ используя CTR+Z всего один раз. Т.е запустил скрипт, свернул его, вернул опять, и дальше я уже не могу не свернуть или даже просто остановить.

ps: запуск с добавлением логического И в конце, ничего не меняет.



я в терминале ввожу ./name.py далее CTR+Z перевожу его ‘сворачиваю’ и когда требуется достаю с помощью bg

Вроде раньше bg отправлял job в background а для «доставания» в foreground использовался fg ?

Ctrl+Z не сворачивает, а ставит на паузу. «Сворачивает» bg , разворачивает fg .



открепить процесс от терминала. он по-прежнему не будет демоном, но вывод будет перенаправлен в файл. емнип, это необратимо

nohup python script.py &

  1. запускать в мультиплексоре терминалов вроде screen или tmux. опять же, это ни разу не демон, но ты можешь отключаться от сессии scren/tmux и по желанию подключаться снова

Пробую: code=nohup python 1.py > logs.txt& но ничего не выходит

Хочу на наглядном примере просто понять, каким самым простым способом я могу запустить скрипт в фоне и писать его результат работы его в файл, и если мне необходимо то вернуть его снова из фона.

Hex-Value ( 27.11.19 20:59:38 )
Последнее исправление: Hex-Value 27.11.19 21:21:26 (всего исправлений: 5)


Используйте screen или tmux для такого.


Для прототипа и тестов как написали выше screen или tmux.

В продакшене лучше что-нибудь серьезное использовать вроде supervisor

А зачем возвращать в foreground? Если настроить логирование для stdout/err то результат работы можно прочитать из файла.


ЕМНИП, процесс тупо будет запущен в фоне, но прикреплён к тому же терминалу. При закрытии ssh сессии он будет убит, так что без nohup не катит

$ systemd-run –user ./script.py

nohup если не пользуешься системным менеджером


… что полностью устраивает ТСа, не?

Задача: Хожу на сервер по ssh запускаю скрипт в фоне, который весь свой вывод в процессе работы ‘ложит’ в файл, скрипт должен работать бесконечно. Естественно я буду периодически переподключаться к серверу по ssh. Очень желательно иметь возможность вернуть скрипт из ‘фона’ каждый раз при подключении по ssh и посмотреть результат его работы в реальном времени.

Подвиду под общий знаменатель то что понял, у меня выбор один это использовать nohup, если я запускаю скрипт к примеру:

nohup ./script.py > logs.txt

PS: Люди выше писали про screen и tmux, я вкурсе их существования и даже использую, но как они мне помогут запускать скрипт в фоне на удаленном сервере я не совсем понимаю.

Hex-Value ( 29.11.19 01:26:25 )
Последнее исправление: Hex-Value 29.11.19 01:28:39 (всего исправлений: 1)


ты либо альтернативный, либо прикидываешься. тебе нужны либо screen, либо tmux. задача же, которую ты решаешь - дебильная.


выше писали про screen и tmux, я вкурсе их существования и даже использую, но как они мне помогут запускать скрипт в фоне на удаленном сервере я не совсем понимаю.

screen -S jobs_name -d -m /your/script.sh запустит твой скрипт «в фоне», затем можешь закрывать ssh-сессию, отключаться,

подключаться снова, выполнишь screen -ls – он тебе выкатит список сейчас выполняющихся,

по screen -x имя_сессий можешь подключиться и посмотреть что там происходит

Как правило, выполнение команд в терминале связано с одним неудобством — прежде чем приступить к вводу следующей команды, следует дождаться выполнения предыдущей. Это происходит, поскольку текущий процесс блокирует доступ к оболочке операционной системы и в таких случаях говорят, что команда выполняется на переднем плане. Что же делать, если нужно запустить несколько команд одновременно? Есть несколько решений. Первое и наиболее очевидное — открыть дополнительное окно терминала. Второе — инициировать выполнение команды в фоновом режиме.

Если какой-либо процесс происходит в фоновом режиме, это значит, что он не предусматривает взаимодействия с пользователем, следовательно, доступ к оболочке остается свободным. Прочитав эту статью, вы узнаете как запустить процесс в фоне Linux и что делать, чтобы их выполнение не прерывалось после закрытия терминала.

Как запустить процесс в фоне Linux

Для выполнения команды в фоновом режиме достаточно добавить в конце символ амперсанда (&):

В выводе терминала будут отображены порядковый номер задачи (в квадратных скобках) и идентификатор процесса:


В фоновом режиме можно одновременно запускать сразу два, три, четыре процесса и даже больше.

Здесь >/dev/null 2>&1 обозначает, что stdout будет перенаправлен на /dev/null, а stderr — к stdout.


Узнать состояние всех остановленных и выполняемых в фоновом режиме задач в рамках текущей сессии терминала можно при помощи утилиты jobs c использованием опции -l:

Вывод содержит порядковый номер задачи, идентификатор фонового процесса, состояние задачи и название команды, которая запустила задание.


В любое время можно вернуть процесс из фонового режима на передний план. Для этого служит команда fg:

Если в фоновом режиме выполняется несколько программ, следует также указывать номер. Например:


Для завершения фонового процесса применяют команду kill с номером программы:


Как перевести процесс в фоновый режим

Если изначально процесс был запущен обычным способом, его можно перевести в фоновый режим, выполнив следующие действия:

  1. Остановить выполнение команды, нажав комбинацию клавиш Ctrl+Z.
  2. Перевести процесс в фоновый режим при помощи команды bg.


Работа процессов в фоне

Запуск скрипта в фоне linux - это одно, но надо чтобы он ещё работал после закрытия терминала. Закрытие терминала путем нажатия на крестик в верхнем углу экрана влечет за собой завершение всех фоновых процессов. Впрочем, есть несколько способов сохранить их после того как связь с интерактивной оболочкой прервется. Первый способ — это удаление задачи из очереди заданий при помощи команды disown:

Как и в предыдущих случаях, при наличии нескольких одновременно выполняемых процессов следует указывать номер того, относительно которого будет выполнено действие:


Убедиться, что задачи больше нет в списке заданий, можно, использовав уже знакомую утилиту jobs -l. А чтобы просмотреть перечень всех запущенных процессов (в том числе и отключенных) применяется команда

Второй способ сохранить запущенные процессы после прекращения работы терминала — команда nohup. Она выполняет другую команду, которая была указана в качестве аргумента, при этом игнорирует все сигналы SIGHUP (те, которые получает процесс при закрытии терминала). Для запуска команды в фоновом режиме нужно написать команду в виде:


Как видно на скриншоте, вывод команды перенаправляется в файл nohup.out. При этом после выхода из системы или закрытия терминала процесс не завершается. Существует ряд программ, которые позволяют запускать несколько интерактивных сессий одновременно. Наиболее популярные из них — Screen и Tmux.

  • Screen либо GNU Screen — это терминальный мультиплексор, который позволяет запустить один рабочий сеанс и в рамках него открыть любое количество окон (виртуальных терминалов). Процессы, запущенные в этой программе, будут выполняться, даже если их окна невидимы или программа прекратила работу.
  • Tmux — более современная альтернатива GNU Screen. Впрочем, возможности Tmux не имеют принципиальных отличий — в этой программе точно так же можно открывать множество окон в рамках одного сеанса. Задачи, запущенные в Tmux, продолжают выполняться, если терминал был закрыт.

Выводы

Чтобы запустить скрипт в фоне linux, достаточно добавить в конце знак &. При запуске команд в фоновом режиме отпадает необходимость дожидаться завершения одной команды для того, чтобы ввести другую. Если у вас возникли вопросы, обязательно задавайте их в комментариях.

Запускаем Python-скрипт с помощью Cron на Linux

Вспомнив про ранее купленный VPS, куда я деплоил свой tf-idf кластеризатор. Было решено залить скрипт на сервер и настроить его запуск на 6 утра ежедневно.

Устанавливаем Python на сервер

Выполняем, указные команды на примере Ubuntu.

Проверяем успешность установки командой python3.

Создаем виртуальное окружение virtalenv

создание venv python linux

Запуск Python-скрипта с помощью Сron

Давай потестируем то, что у нас получилось на маленьком скрипте, который будет писать в файл дату и время его активации. Таким образом мы проверим как работает cron. Тестовый скрипт, который мы положим в корень папки проекта, у меня это / home / iakulshin / pipeline, заливаем через файловый менеджер filezilla и прочие, если вы хардкорный девопс-дата-инженер удачи вам с nano. Заливаем скрипт указанный ниже в нашу папку.

Давайте попробуем создать cron задание для тестового запуска. В целом нам будут нужны 2 команды:

Появлеятся файлик с крон задачами в редакторе nano. Наша задача установить задание, которое будет запускать наш скрипт каждую минуту.

Наконец, в файлике test.txt каждую минуту появляется текущая дата, учения завершены, теперь рассмотрим возможные проблемы и способы их устранения.

Как понять что Cron срабатывает?

Чтобы удостовериться, что cron-таск отрабатывает, нам необходимо добавить задачу и обратиться к логам сервера, для этого идем в консоль и пишем следующую команду:

как понять что cron сработала

В нем вы увидите следующие записи:

Это означает, что cron срабатывает и воспроизводит команду, которую вы указали после звездочек. Но что делать, если python-скрипт всё еще не работает?

Cron срабатывает но Python-скрипт не выполняется

Возьмите команду, которую собирались добавь в крон и запустите её, это поможет словить ошибки связанные с недоступностью библиотек. В моем случае Скрипт не видел импортируемый файл, это я вылечил добавлением папки в системный путь. Добавляем в скрипты следующий код:

Если скрипт запускается по прямой команде из консоли, но cron всё еще не выполняется, то ошибка 100% в том, что ваш скрипт запускается не из под virtualenv или вы запускаете скрипт из под python не подходящей версии, поэтому проверяем следующее:

  1. Мы перешли в папку со скриптом командой cd
  2. Мы обратились к интерпретатору python3 находящемуся в папке с виртуальным окружением нашего проекта.

В целом данный гайд должен помочь вам разобраться с запуском Python скриптов с помощью Cron. Однако, я оставлю ссылки на полезные треды в stackoverflow, где представлены дополнительные способы решения этой проблемы.

Читайте также: