Запустить скрипт 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 &
- запускать в мультиплексоре терминалов вроде 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 с номером программы:
Как перевести процесс в фоновый режим
Если изначально процесс был запущен обычным способом, его можно перевести в фоновый режим, выполнив следующие действия:
- Остановить выполнение команды, нажав комбинацию клавиш Ctrl+Z.
- Перевести процесс в фоновый режим при помощи команды bg.
Работа процессов в фоне
Запуск скрипта в фоне linux - это одно, но надо чтобы он ещё работал после закрытия терминала. Закрытие терминала путем нажатия на крестик в верхнем углу экрана влечет за собой завершение всех фоновых процессов. Впрочем, есть несколько способов сохранить их после того как связь с интерактивной оболочкой прервется. Первый способ — это удаление задачи из очереди заданий при помощи команды disown:
Как и в предыдущих случаях, при наличии нескольких одновременно выполняемых процессов следует указывать номер того, относительно которого будет выполнено действие:
Убедиться, что задачи больше нет в списке заданий, можно, использовав уже знакомую утилиту jobs -l. А чтобы просмотреть перечень всех запущенных процессов (в том числе и отключенных) применяется команда
Второй способ сохранить запущенные процессы после прекращения работы терминала — команда nohup. Она выполняет другую команду, которая была указана в качестве аргумента, при этом игнорирует все сигналы SIGHUP (те, которые получает процесс при закрытии терминала). Для запуска команды в фоновом режиме нужно написать команду в виде:
Как видно на скриншоте, вывод команды перенаправляется в файл nohup.out. При этом после выхода из системы или закрытия терминала процесс не завершается. Существует ряд программ, которые позволяют запускать несколько интерактивных сессий одновременно. Наиболее популярные из них — Screen и Tmux.
- Screen либо GNU Screen — это терминальный мультиплексор, который позволяет запустить один рабочий сеанс и в рамках него открыть любое количество окон (виртуальных терминалов). Процессы, запущенные в этой программе, будут выполняться, даже если их окна невидимы или программа прекратила работу.
- Tmux — более современная альтернатива GNU Screen. Впрочем, возможности Tmux не имеют принципиальных отличий — в этой программе точно так же можно открывать множество окон в рамках одного сеанса. Задачи, запущенные в Tmux, продолжают выполняться, если терминал был закрыт.
Выводы
Чтобы запустить скрипт в фоне linux, достаточно добавить в конце знак &. При запуске команд в фоновом режиме отпадает необходимость дожидаться завершения одной команды для того, чтобы ввести другую. Если у вас возникли вопросы, обязательно задавайте их в комментариях.
Вспомнив про ранее купленный VPS, куда я деплоил свой tf-idf кластеризатор. Было решено залить скрипт на сервер и настроить его запуск на 6 утра ежедневно.
Устанавливаем Python на сервер
Выполняем, указные команды на примере Ubuntu.
Проверяем успешность установки командой python3.
Создаем виртуальное окружение virtalenv
Запуск Python-скрипта с помощью Сron
Давай потестируем то, что у нас получилось на маленьком скрипте, который будет писать в файл дату и время его активации. Таким образом мы проверим как работает cron. Тестовый скрипт, который мы положим в корень папки проекта, у меня это / home / iakulshin / pipeline, заливаем через файловый менеджер filezilla и прочие, если вы хардкорный девопс-дата-инженер удачи вам с nano. Заливаем скрипт указанный ниже в нашу папку.
Давайте попробуем создать cron задание для тестового запуска. В целом нам будут нужны 2 команды:
Появлеятся файлик с крон задачами в редакторе nano. Наша задача установить задание, которое будет запускать наш скрипт каждую минуту.
Наконец, в файлике test.txt каждую минуту появляется текущая дата, учения завершены, теперь рассмотрим возможные проблемы и способы их устранения.
Как понять что Cron срабатывает?
Чтобы удостовериться, что cron-таск отрабатывает, нам необходимо добавить задачу и обратиться к логам сервера, для этого идем в консоль и пишем следующую команду:
В нем вы увидите следующие записи:
Это означает, что cron срабатывает и воспроизводит команду, которую вы указали после звездочек. Но что делать, если python-скрипт всё еще не работает?
Cron срабатывает но Python-скрипт не выполняется
Возьмите команду, которую собирались добавь в крон и запустите её, это поможет словить ошибки связанные с недоступностью библиотек. В моем случае Скрипт не видел импортируемый файл, это я вылечил добавлением папки в системный путь. Добавляем в скрипты следующий код:
Если скрипт запускается по прямой команде из консоли, но cron всё еще не выполняется, то ошибка 100% в том, что ваш скрипт запускается не из под virtualenv или вы запускаете скрипт из под python не подходящей версии, поэтому проверяем следующее:
- Мы перешли в папку со скриптом командой cd
- Мы обратились к интерпретатору python3 находящемуся в папке с виртуальным окружением нашего проекта.
В целом данный гайд должен помочь вам разобраться с запуском Python скриптов с помощью Cron. Однако, я оставлю ссылки на полезные треды в stackoverflow, где представлены дополнительные способы решения этой проблемы.
Читайте также: