Как перезапустить сценарий Python автоматически, если он уничтожается или умирает

vncserver не соединяется с фактическим рабочим столом; это создает виртуальный рабочий стол, который настроен отдельно. Если Вы хотите получить доступ к фактическому рабочему столу затем, необходимо использовать или VNC X расширений или Винишко.

32
05.01.2014, 21:01
10 ответов

На Ubuntu (пока 14.04, 16.04 и более позднее использование systemd) не может использовать выскочку, чтобы сделать так, лучше, чем задание крона. Вы вставляете установку конфигурации /etc/init и удостоверьтесь, что Вы указываете переикру

Это мог быть минимальный файл /etc/init/testing.conf (редактирование как root):

chdir /your/base/directory
exec python testing.py
respawn

И можно протестировать с /your/base/directory/testing.py:

from __future__ import print_function

import time

with open('/var/tmp/testing.log', 'a') as fp:
    print(time.time(), 'done', file=fp)
    time.sleep(3)

и запустите с:

sudo start testing

и следуйте за тем, что происходит (в другом окне) с:

tail -f /var/tmp/testing.log

и остановитесь с:

sudo stop testing

Можно также добавить [start on][2] чтобы иметь команду запускаются на начальной загрузке системы.

24
27.01.2020, 19:37
  • 1
    При использовании задания крона затем, Вы захотите или реализовать или найти некоторый код для устойчивой обработки файла PID. Вы хотите сделать, чтобы Ваш сервис/сценарий/демон создал файл PID (традиционно расположенный под/var/run) и имел его проверку кода запуска, если содержание файла является устаревшим (оставленный уничтоженным процессом). Этот вид кода удивительно трудно записать свободный от угловых случаев и гонок. stackoverflow.com/questions/788411 / … –  Jim Dennis 05.01.2014, 10:08
  • 2
    @Zelda: Спасибо за предложение.. Я плохо знаком с миром Linux/Unix.. В каких изменениях я, как предполагается, вношу /etc/init файл? Если можно предоставить пошаговое руководство мне, то я смогу изучить что-то и сделать правильную вещь.. –  arsenal 05.01.2014, 10:24
  • 3
    @Webby я сделал ответ больше завершенный. Если Вы не хотите открывать файл для вывода, и переписать Ваши операторы печати можно сделать что-то как sys.stdout = open(file_name, 'w') вначале. –  Zelda 05.01.2014, 12:29
  • 4
    . Ценивший Ваша справка.. Я обновил вопрос с некоторыми деталями.. Я пытаюсь сделать как это, чтобы видеть, работает ли мой testing.py или нет.. Это не делает показывает мне, работает ли это или нет.. px ax | grep testing.py.. Это возвращает меня ничто? Какая-либо идея, почему? –  arsenal 05.01.2014, 20:58
  • 5
    Необходимо поместить все это в пункт попытки/кроме и записать в файл журнала, какое исключение было сгенерировано и что программа выходит. Возможно, оператор печати не работает, поскольку он не может записать в stdout. –  Zelda 05.01.2014, 21:35

Вы могли также проявить ориентированный подход большего количества оболочки. Имейте Ваш cron ищите свой сценарий и повторно запустите его, если он умирает.

  1. Создайте новый crontab путем выполнения crontab -e. Это поднимет окно Вашего любимого текстового редактора.

  2. Добавьте эту строку к файлу, который просто открылся

    */5 * * * * pgrep -f testing.py || nohup python /home/you/scripts/testing.py > test.out
    
  3. Сохраните файл и выйдите из редактора.

Вы просто создали новое crontab который будет выполняться каждые 5 минут и запустит Ваш сценарий, если он не будет уже работать. Посмотрите здесь для миленького учебного руководства на cron. Официальные документы Ubuntu о cron здесь.

Фактическая выполняемая команда pgrep который ищет рабочие процессы строку, данную в командной строке. pgrep foo будет искать названную программу foo и возвратите его идентификатор процесса. pgrep -f делает это искать всю командную строку раньше запускало программу и не только название программы (полезный, потому что это - сценарий Python).

|| средства символа "делают это, если предыдущая команда перестала работать". Так, если Ваш сценарий не работает, pgrep перестанет работать, так как это ничего не найдет, и Ваш сценарий будет запущен.

21
27.01.2020, 19:37
  • 1
    .. Но я плохо знаком с Linux и Unix, так не знайте, где crontab? Действительно ли это - файл в моей машине человечности где-нибудь? –  arsenal 05.01.2014, 11:26
  • 2
    @Webby видит обновленный ответ. –  terdon♦ 05.01.2014, 11:31
  • 3
    Спасибо terdon.. Я могу выполнить эту команду crontab -e из каталога, где мой сценарий Python.. Корректный? –  arsenal 05.01.2014, 11:42
  • 4
    @Webby можно выполнить его отовсюду, Вы хотите. cron демон планирования, это - сервис, который работает в фоновом режиме. Если Ваш сценарий Python не находится в Вашем $PATH (если Вы не можете запустить его ниоткуда, но должны быть в его каталоге), используют полный путь для сценария как в моем обновленном ответе. –  terdon♦ 05.01.2014, 11:44
  • 5
    Спасибо. Теперь это имеет смысл.. Я просто создал новый crontab и отредактировал файл путем добавления той же одной строки, но в течение 1 минуты.. Я уже создал Привет Мир сценарий Python, вращающийся вокруг, в то время как Верный назвал как testing.py.. После того, чтобы сохранить crontab файл это должно автоматически запустить testing.py после 1 минуты? И затем продолжите проверять каждую 1 минуту, работает ли сценарий Python или нет? Если да, после сохранения crontab-e файл, я сделал топор PS | grep testing.py, и я не могу видеть какой-либо процесс для этого? –  arsenal 05.01.2014, 12:11

Вы можете иметь перенаправление программы тестирования вывод с помощью параметра командной строки и затем использовать простой сценарий Python для перезапуска программы неограниченно долго:

import subprocess

while True:
    try:
        print subprocess.check_output(['python', 'testing.py'])
    except KeyboardInterrupt:
        break

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

6
27.01.2020, 19:37

Вы не должны действительно использовать это для производства, но Вы могли:

#!/bin/sh

while true; do
  nohup python testing.py >> test.out
done &

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

6
27.01.2020, 19:37

Существует много способов контролировать и повторно породить процессы под UNIX/Linux. Один из самых старых является записью "переикры" в/etc/inittab... при использовании старой системы SysV init. Другой метод должен использовать демона супервизора от daemontools пакета ди-джея Bernstein. Другие опции состоят в том, чтобы использовать функции в выскочке Ubuntu... или systemd или других.

Но можно посмотреть на альтернативы init и в коде Python для Pardus: демон mudur в частности.

Если Вы решаете пойти с заданием крона (и обработка файла PID) затем рассматривают чтение этого PEP 3143 и возможно использование его ссылочной реализации.

Когда я сослался на в моих других комментариях, устойчивая обработка файла PID хитра. Это подвержено угловым случаям и гонкам. Это становится более хитрым, если существует шанс, что Ваш файл PID заканчивается на NFS, или другая сетевая файловая система (часть атомарности гарантирует, что Вы добираетесь с семантикой обработки файла в надлежащих локальных файловых системах UNIX/Linux, уходят на некоторых версиях и реализациях NFS, например). Также семантика вокруг захвата файла под UNIX может быть хитрой. (Делает flock или fcntl блокировка выпущена быстро в Вашей целевой ОС, когда процесс, содержащий ее, уничтожается с SIGKILL, например?).

6
27.01.2020, 19:37

Можно также использовать monit Или Процесс, контролирующий с наблюдателем PS

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

Вот пример для Вашего сценария:

check process myprocessname
        matching "myprocessname"
        start program = "nohup /usr/bin/python /path/testing.py > /tmp/test.out &"
        stop program = "/usr/bin/killall myprocessname"

Бросьте взгляд на monit примеры

3
27.01.2020, 19:37

Вам нужен супервизор, можно использовать супервизор. Это - основанный на Python супервизор, поэтому легкий изменить, если Вы должны.

Управление с файлами с .ini синтаксисом файла.

1
27.01.2020, 19:37

Ответ Тердона, у меня не сработал, потому что pgrep -f testing.py никогда не давал сбоев. Он получит pid для задания cron (из-за опции -f). Однако без параметра -f pgrep не найдет testing.py, потому что нет процесса с именем testing.py.

Мое решение состояло в том, чтобы изменить

pgrep -f testing.py

на

pgrep -f testing.py | pgrep python

, это означает, что полное задание crontab будет следующим:

*/5 * * * * pgrep -f testing.py | pgrep python || nohup python /home/you/scripts/testing.py > test.out
0
27.01.2020, 19:37

Что касается ответа тердона, pgrep -f testing.pyникогда не вернет false в соответствии с комментариями в здесь:

I think the issue is that cron spawns a shell to run your command, and the arguments of that shell are matched by pgrep since you are using -f

Для ответа Мэтта pgrep -f testing.pyбесполезен, поскольку pgrep pythonсоответствует любому работающему скрипту Python. Итак, если два скрипта Python cronjob, второй cronjob никогда не запустится.

И тут я нашел решение pgrep -f testing.pyв комментарии здесь:https://askubuntu.com/questions/1014559/running-pgrep-in-a-crontab?noredirect=1&lq=1

Мой cron для запуска двух Python-скриптов:

* * * * * pgrep -f '^/usr/bin/python36 /home/ec2-user/myscript1\.py' || nohup /usr/bin/python36 /home/ec2-user/myscript1.py

0 * * * * pgrep -f '^/usr/bin/python36 /home/ec2-user/myscript2\.py' || nohup /usr/bin/python36 /home/ec2-user/myscript2.py
0
27.01.2020, 19:37

В моем случае, в качестве быстрого -исправления, я хотел, чтобы моя программа работала, когда она завершилась с ошибкой en или была убита. С другой стороны, я хотел остановить выполнение, когда программа завершилась правильно (код возврата = 0)

Я проверил это на Bash. Он должен нормально работать в любой другой оболочке

#!/bin/sh

echo ""
echo "Use: $0./instagram.py"
echo ""

echo "Executing $1..."

EXIT_CODE=1
(while [ $EXIT_CODE -gt 0 ]; do
    $1
    # loops on error code: greater-than 0
    EXIT_CODE=$?
done)
0
27.01.2020, 19:37

Теги

Похожие вопросы