Перезапуск самообновляющегося скрипта python
Я написал скрипт, который будет держать себя в курсе, загрузив последнюю версию с сайта и перезаписи скрипта.
Я не уверен, что лучший способ перезапустить скрипт после его обновления.
какие идеи?
Я не хочу иметь отдельный скрипт обновления. о, и он должен работать и на linux/windows тоже.
8 ответов
в Linux или любой другой форме unix, os.execl и друзья-хороший выбор для этого-вам просто нужно re-exec sys.исполняемый С теми же параметрами, что и в прошлый раз (sys.argv
, более или менее) или любой их вариант, если вам нужно сообщить своему следующему воплощению, что это на самом деле перезапуск. На Windows, os.spawnl (и друзья) - это лучшее, что вы можете сделать (хотя это займет больше времени и памяти, чем ОС.execl и друзья бы во время перехода).
проект CherryPy имеет код, который перезапускается. Вот!--2-->как они это делают:
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)
я использовал этот метод в своем собственном коде, и он отлично работает. (Я не потрудился сделать шаг цитирования аргументов в windows выше, но, вероятно, это необходимо, если аргументы могут содержать пробелы или другие специальные символы.)
Я думаю, что лучшим решением было бы что-то вроде этого:
ваша обычная программа:
...
# ... 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")
сценарий обновления: (например: home/code/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")
Я надеюсь, что это поможет вам.
самым чистым решением является отдельный скрипт обновления!
запустить программу внутри него, отчет (при выходе), что доступна новая версия. Это позволяет программе сохранить все свои данные, программе обновления применить обновление и запустить новую версию, которая затем загружает сохраненные данные и продолжает работу. Для пользователя это может быть полностью прозрачным, так как они просто запускают updater-shell, который запускает реальную программу.
команда pocoo имеет очень хороший перегружатель для своего сервера разработки внутри werkzueg. Проверьте код здесь (это в нижней части файла).
Главная Файл:
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) Если функция обновления нуждается в обновлении, то она обновляет и вызывает новые экземпляры "main"
затем выходит исходный экземпляр "main".
2) Если функция обновления не нуждается в обновлении, то" main " продолжает работать
для дополнительной поддержки вызовов скриптов с параметром Python "- m " можно использовать следующее (на основе ответа Alex; версия 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()