2009-11-17 67 views
30

私は最新のバージョンをWebサイトからダウンロードし、実行中のスクリプトを上書きすることで、最新の状態に保つスクリプトを作成しました。自己更新Pythonスクリプトの再起動

スクリプトが更新された後にスクリプトを再起動する最良の方法がわかりません。

アイデア?

私は本当に別のアップデートスクリプトを持っているとは思っていません。 ああ、それは両方のLinux/Windowsでも動作する必要があります。

答えて

26

Linuxやその他のUNIX形式の場合は、os.execlと友人がこれに適しています。sys.executableは前回実行時と同じパラメータで再実行するだけです(sys.argv、多かれ少なかれ)あなたが次回のインカネーションに実際に再起動したことを通知する必要がある場合は、その任意の変種を使用してください。 Windowsでは、os.spawnl(および友人)はあなたができる最高のものです(ただし、過渡的にos.execlよりも時間とメモリが多くなり、移行中に友人がいます)。

+0

おそらく、スクリプトが十分に単純であれば最良の方法です。 –

+0

os.execlもウィンドウ上で動作します。 – Josh

+23

今後の参考のために、 'os.execl(sys.executable、*([sys.executable] + sys.argv))' – Claudiu

1

pocooチームは、werkzuegの開発サーバー用に非常に良いリローダを持っています。コードhereをチェックしてください(ファイルの最後に向かっています)。

+0

このリンクは現在無効です。別のものはありますか? – Glycerine

+0

githubに移動したようです:[werkzeug/serving.py](https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/serving.py) – johnny

+0

ありがとう!リンクを更新しました。 –

2

最もクリーンな解決策は、別のアップデートスクリプトです!

プログラムを実行して、新しいバージョンが利用可能であることを報告してください(終了時)。これにより、プログラムはすべてのデータを保存し、アップデータは更新を適用し、新しいバージョンを実行し、保存されたデータをロードして処理を続行します。ユーザーには、実際のプログラムを実行するupdater-shellを実行するだけで完全に透過的にすることができます。

+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を呼び出す)、更新する場合関数は更新する必要があります"メイン"の新しいインスタンスを呼び出します

"main"の元のインスタンスが終了します。

2)は、更新機能を更新する必要がない場合には、「メイン」に加えて、スクリプトをサポートするために

0

を実行し続けアレックスの回答に基づいて使用することができる(Pythonの「-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() 
関連する問題