Webサイトから最新バージョンをダウンロードして実行中のスクリプトを上書きすることにより、最新の状態に保つスクリプトを作成しました。
スクリプトが更新された後にスクリプトを再起動するための最良の方法はわかりません。
何か案は?
個別の更新スクリプトは必要ありません。ああ、それは両方のlinux/windowsでも動作する必要があります。
Linux、またはその他のUNIXの形式では、 os.execl や友人がこれに適しています-同じことで sys.executable を再実行する必要があるだけです前回実行されたパラメータ(sys.argv
、多かれ少なかれ)またはそれが実際に再起動であることを次のインカネーションに通知する必要がある場合は、そのバリアント。 Windowsでは、 os.spawnl (および友人)があなたにできる最高のことです(ただし、移行中にos.execlや友人よりも一時的に多くの時間とメモリが必要になります)。
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)
私はこのテクニックを自分のコードで使用しましたが、うまく機能します。 (上記のウィンドウで引数の引用手順を実行する必要はありませんでしたが、引数にスペースやその他の特殊文字を含めることができる場合はおそらく必要です。)
私はこのようなものである最善の解決策だと思います:
通常のプログラム:
...
# ... 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")
これがお役に立てば幸いです。
最もクリーンなソリューションは、独立した更新スクリプトです!
その中でプログラムを実行し、新しいバージョンが利用可能であることを(終了時に)報告します。これにより、プログラムですべてのデータを保存し、アップデーターで更新を適用し、新しいバージョンを実行して、保存したデータをロードして続行できます。ユーザーにとっては、実際のプログラムを実行するアップデータシェルを実行するだけなので、これは完全に透過的です。
Poconoチームは、開発サーバー用の非常に優れたリローダーをwerkzeug内部に持っています。コードを確認してください here (ファイルの下部にあります)。
さらに、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()
reload(module) を使用してモジュールをリロードできます。
メインファイル:
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」の新しいインスタンスを更新して呼び出す
次に、「メイン」の元のインスタンスが終了します。
2)更新機能を更新する必要がない場合、「メイン」は引き続き実行されます