我编写了一个脚本,通过从网站下载最新版本并覆盖正在运行的脚本来保持自己的最新状态。
我不确定在更新脚本后重启脚本的最佳方法是什么。
有什么想法吗?
我真的不想拥有单独的更新脚本。 哦,它也必须在linux / windows上工作。
答案 0 :(得分:27)
在Linux或任何其他形式的unix中,os.execl和朋友是一个很好的选择 - 你只需要重新执行sys.executable与上次执行的相同参数(sys.argv
,或多或少)或其任何变体,如果您需要通知您的下一个化身,它实际上是重新启动。在Windows上,os.spawnl(以及朋友)是你能做的最好的事情(虽然它会比os.execl和朋友在转换过程中花费更多的时间和内存。)
答案 1 :(得分:16)
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)
我在自己的代码中使用了这种技术,效果很好。 (我没有在上面的窗口上做参数引用步骤,但如果参数可以包含空格或其他特殊字符,则可能是必要的。)
答案 2 :(得分:3)
我认为最好的解决方案是这样的:
您的正常计划:
...
# ... 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")
我希望这会对你有所帮助。
答案 3 :(得分:2)
最干净的解决方案是单独的更新脚本!
在其中运行您的程序,报告(退出时)新版本可用。这允许程序保存其所有数据,更新程序以应用更新,并运行新版本,然后加载保存的数据并继续。对于用户来说,这可以是完全透明的,因为它们只运行运行真实程序的updater-shell。
答案 4 :(得分:1)
pocoo团队为werkzueg内部的开发服务器提供了非常好的重新加载器。检查代码here(它位于文件底部)。
答案 5 :(得分:0)
您可以使用reload(module)重新加载模块。
答案 6 :(得分: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)如果更新功能需要更新,则更新并调用“main”的新实例
然后“main”的原始实例退出。
2)如果更新功能不需要更新,则“main”继续运行
答案 7 :(得分:0)
要使用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()
答案 8 :(得分:0)
做这样的事情会不会更容易 非常简单,不需要额外的导入,并且可以与任何操作系统兼容,具体取决于您在os.system字段中输入的内容
def restart_program():
print("Restarting Now...")
os.system('your program here')