2014-09-30 4 views
1

Я работаю над скриптом Python, который должен перезапустить сам.Процесс перезагрузки через Bash

Это то, что я делаю в сценарии Python

os.execl('run.sh', '') 

Мой run.sh тогда выглядит так

#!/bin/bash 
sudo fuser -ku 8000/tcp 
python /home/app.py 

Причина я использую sudo fuser -ku 8000/tcp потому, что это было отчасти легко, потому что мой питон скрипт был единственным, использующим порт 8000.

Когда я запускаю скрипт python, он делает это и останавливается.

8000/tcp:    7587(pi) 7596(pi) 7597(pi) 7605(pi) 7606(root) 
./run.sh: line 3: 7587 Killed     python /home/app.py 

Он никогда не перезапускает скрипт python.

ответ

2

В соответствии с документацией os.execl() эта функция заменяет текущий процесс Python и никогда не возвращается. Так что у вас есть это:

  • Python работает, вызывает execl (run.sh), теперь уже не работает
  • run.sh работает, использует Sudo по какой-то причине безбожной (тот же пользователь может убить без Судо !), пытается найти программу Python, используя ее номер порта (?!) и убивает его (или нет, поскольку вы вообще не обрабатываете ошибки в сценарии оболочки).
  • run.sh (если он еще жив после всего этого убийства) пытается запустить скрипт Python.

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

os.execlp('python', '/home/app.py') 

Для бонусных баллов, вы можете получить текущий Python и скрипт (например, с использованием sys.argv) и использовать только те, вместо того, чтобы их жесткое кодирование. Подробную информацию об этом см. Здесь: Restarting a self-updating python script

+0

Спасибо! Вы решение занимает меня на полпути. Он перезапускает скрипт python, но сервер Flask, который я запускаю в скрипте, дает мне эту ошибку: ошибка: [Errno 98] Адрес уже используется – Filip

+0

Посмотрите 'SO_REUSEADDR', чтобы исправить это. –

+0

Я не могу найти что-либо подобное для Flask, чтобы каким-то образом разоблачить сокет, используемый Flask? – Filip

0

Когда выполняется код python, он создает sys.argv.

when Python is invoked, it sets sys.argv to everything but it's own executable.

Так Вам нужно будет использовать как os.execlp('python', 'the_directory')

Пожалуйста, смотрите here для подробного ответа на его работы.

0

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

скелет кода может выглядеть так:

  • питон скрипт запускается и пытается связать определенный сокет Unix. Имя сокета должно начинаться с нулевого байта, потому что это гарантирует, что сокет замирает, когда процесс выполняется. (это ссылается на пространство имен абстрактных Socket Linux)
    • Если это удается, это означает, что предыдущий запущенный экземпляр сервера отсутствует.Свяжите TCP-сервер с портом 8000 и принимайте соединения и обрабатывайте эти запросы. Слушайте сокет UNIX для следующего прихода экземпляра python. когда вы подключаетесь к этому сокету UNIX, прекратите принимать входящие соединения на сокет TCP-сервера, затем передайте этот файловый дескриптор в следующий экземпляр, а затем весь файловый дескриптор других клиентов (или если запросы быстро заканчиваются для их обработки). Затем умри.
    • Если это не удается, это означает, что есть предыдущий запущенный экземпляр. Затем подключитесь к нему, поздоровайтесь и получите через него все дескрипторы файлов. Первый - это сокет TCP-сервера, поэтому начните принимать на нем новые соединения. Другие файловые дескрипторы являются одними из уже подключенных клиентов ...

С этим методом возможно построить действительно прозрачную перезагрузку сервера. Вам нужна дополнительная библиотека для передачи дескрипторов файлов из одного процесса в другой: http://code.google.com/p/python-passfd/

Смежные вопросы