2009-11-17 20 views
30

Я написал сценарий, который будет обновляться, загружая последнюю версию с веб-сайта и перезаписывая исполняемый скрипт.Перезапуск самообновляющегося скрипта python

Я не уверен, что лучший способ перезапустить скрипт после его обновления.

Любые идеи?

Я действительно не хочу иметь отдельный сценарий обновления. ой, и он должен работать и на linux/windows тоже.

ответ

26

В Linux, или любая другая форма Unix, os.execl и друзьями являются хорошим выбором для этого - нужно просто заново EXEC sys.executable с теми же параметрами, что был исполнен с последний раз (sys.argv, более или менее) или любой его вариант, если вам необходимо сообщить вашему следующему воплощению, что это фактически перезапуск. В Windows os.spawnl (и друзья) - это лучшее, что вы можете сделать (хотя на переходном этапе потребуется больше времени и памяти, чем os.execl, а друзья будут во время перехода).

+0

Вероятно, лучший способ пойти, если скрипт достаточно прост. –

+0

os.execl работает и над окнами. – Josh

+23

One-liner для справок в будущем: 'os.execl (sys.executable, * ([sys.executable] + sys.argv))' – Claudiu

1

Команда pocoo имеет очень хороший перезарядщик для своего сервера разработки внутри werkzueg. Проверьте код here (он находится в нижней части файла).

+0

Эта ссылка сейчас мертва. Есть еще? – Glycerine

+0

Похоже, они переехали в github: [werkzeug/serve.py] (https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/serving.py) – johnny

+0

Спасибо! Обновлена ​​ссылка. –

2

Чистое решение - отдельный сценарий обновления!

Запустите свою программу внутри нее, сообщите о возврате (при выходе), что доступна новая версия. Это позволяет вашей программе сохранять все свои данные, обновления для применения обновления и запускать новую версию, которая затем загружает сохраненные данные и продолжается. Для пользователя это может быть полностью прозрачным, поскольку они просто запускают оболочку updater, которая запускает настоящую программу.

+0

Затем вы не можете обновить скрипт обновления. – JDiMatteo

+0

Вы можете использовать свою основную программу для проверки обновлений. Когда доступно новое обновление. загрузите новый «update.py» .... затем выполните его. «update.py» закроет старый экземпляр и создаст новый. – Harvey

3

Я думаю, что лучшее решение whould быть что-то вроде этого:

Ваша нормальная программа:

... 

# ... part that downloaded newest files and put it into the "newest" folder 

from subprocess import Popen 

Popen("/home/code/reloader.py", shell=True) # start reloader 

exit("exit for updating all files") 

Обновление сценария: (например: дом/код/​​reloader.py)

from shutil import copy2, rmtree 
from sys import exit 

# maybie you could do this automatic: 
copy2("/home/code/newest/file1.py", "/home/code/") # copy file 
copy2("/home/code/newest/file2.py", "/home/code/") 
copy2("/home/code/newest/file3.py", "/home/code/") 
... 

rmtree('/home/code/newest') # will delete the folder itself 

Popen("/home/code/program.py", shell=True) # go back to your program 

exit("exit to restart the true program") 

Надеюсь, это поможет вам.

15

Проект CherryPy имеет код, который перезапускается. Вот how they do it:

args = sys.argv[:] 
    self.log('Re-spawning %s' % ' '.join(args)) 

    args.insert(0, sys.executable) 
    if sys.platform == 'win32': 
     args = ['"%s"' % arg for arg in args] 

    os.chdir(_startup_cwd) 
    os.execv(sys.executable, args) 

Я использовал эту технику в моем собственном коде, и он прекрасно работает. (Я не потрудился сделать шаг с аргументами на окнах выше, но это, вероятно, необходимо, если аргументы могут содержать пробелы или другие специальные символы.)

0

Главная Файл:

if __name__ == '__main__': 

if os.path.isfile('__config.py'): 
    print 'Development' 
    push.update_server() 
else: 
    e = update.check() 
    if not e: sys.exit() 

Обновление файла:

def check(): 
    e = 1.....perform checks, if something needs updating, e=0; 
    if not e: 
     os.system("python main.pyw") 
    return e 

Вот логика:

Основная программа вызывает функцию обновления

1) Если обновление функция должна обновляться, чем обновлять и вызывает новые экземпляры «основного»

Затем оригинал экземпляра «основных» выходов.

2) Если функции обновления не нужно обновлять, а затем «основные» продолжает работать

0

Для дополнительной поддержки скрипта звонков с «-m» Пайтон параметра следующим может быть использована (на основе ответа на Алексе Версия для Windows):

os.spawnl(os.P_WAIT, sys.executable, *([sys.executable] + 
    (sys.argv if __package__ is None else ["-m", __loader__.name] + sys.argv[1:]))) 
sys.exit() 
Смежные вопросы