重启自我更新的Python脚本

49 投票
8 回答
47347 浏览
提问于 2025-04-15 16:07

我写了一个脚本,它可以通过从一个网站下载最新版本来保持自己更新,并且会覆盖正在运行的脚本。

我不太确定在更新后,最好的方法是什么来重新启动这个脚本。

有什么好主意吗?

我其实不想再写一个单独的更新脚本。而且这个方法还得在Linux和Windows上都能用。

8 个回答

5

我觉得最好的解决方案可能是这样的:

你的普通程序:

...

# ... 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")

希望这能对你有所帮助。

21

CherryPy项目有一段代码可以让它自己重启。这里是他们是怎么做到的:

    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代码中没有处理参数中的引号,但如果参数里可能有空格或其他特殊字符,这一步可能是必要的。)

35

在Linux或者其他类似Unix的系统中,os.execl 及其相关函数是个不错的选择。你只需要用之前运行时的参数(大概就是 sys.argv)重新执行 sys.executable,或者如果你想告诉程序这是一次重启,可以用其他变体。至于Windows,os.spawnl 及其相关函数是你能做到的最好选择(不过在转换过程中,它会暂时占用比 os.execl 和其他函数更多的时间和内存)。

撰写回答