我有一个基于python的GTK应用程序,可加载多个模块。它从(linux)终端运行,如下所示:
./myscript.py --some-flag setting
从程序中,用户可以下载(使用Git)更新的版本。
如果存在/下载,则会出现一个按钮,我希望用新编译的内容(包括依赖项/导入)重新启动程序。最好还是使用sys.argv
的内容重新启动它,以保持所有标志不变。
所以我找不到/需要的是一个很好的重启过程,它会杀死程序的当前实例并使用相同的参数启动一个新的。
此外,该解决方案最适用于Windows和Mac,但并不是必需的。
答案 0 :(得分:33)
您正在寻找os.exec*()
。
答案 1 :(得分:20)
我认为这是一个更详细的答案,因为有时你可能会得到太多的打开文件对象和描述符,这可能导致内存问题或并发连接到网络设备。
import os
import sys
import psutil
import logging
def restart_program():
"""Restarts the current program, with file objects and descriptors
cleanup
"""
try:
p = psutil.Process(os.getpid())
for handler in p.get_open_files() + p.connections():
os.close(handler.fd)
except Exception, e:
logging.error(e)
python = sys.executable
os.execl(python, python, *sys.argv)
答案 2 :(得分:2)
更新 - 上述答案中的一些示例供将来参考
我有runme.sh
#!/bin/bash
kill -9 server.py
python /home/sun/workspace/c/src/server.py &
我有server.py
我需要重启应用程序本身,所以我有:
os.system('runme.sh')
但是没有按照runme.sh重启应用程序本身,所以当我使用这种方式时:
os.execl('runme.sh', '')
然后我能够重新启动
答案 3 :(得分:2)
对我来说,这部分很有魅力:
def restart():
import sys
print("argv was",sys.argv)
print("sys.executable was", sys.executable)
print("restart now")
import os
os.execv(sys.executable, ['python'] + sys.argv)
我知道了 here。
答案 4 :(得分:1)
我知道这个解决方案在技术上并不是你要求的,但是如果你想100%确定你释放了所有东西或者不想依赖依赖关系,你可以从另一个循环中运行脚本:
import os, time
while 1:
os.system("python main.py")
print "Restarting..."
time.sleep(0.2) # 200ms to CTR+C twice
然后您可以像以下一样重新启动main.py:
quit()
答案 5 :(得分:1)
我对#s3niOr的代码有了一点改善。
在我的情况下,python文件的路径中有空格。因此,通过添加适当的格式,可以解决该问题。
请注意,在我的情况下,我的python文件没有其他参数。因此,如果您还有其他论点,则必须加以处理。
这解决了重新启动路径中带有空格的python脚本的问题:
import os
import sys
import psutil
import logging
def restart_program():
"""Restarts the current program, with file objects and descriptors
cleanup
"""
try:
p = psutil.Process(os.getpid())
for handler in p.get_open_files() + p.connections():
os.close(handler.fd)
except Exception, e:
logging.error(e)
python = sys.executable
os.execl(python, python, "\"{}\"".format(sys.argv[0]))
答案 6 :(得分:1)
在Windows上工作 (无参数)
os.startfile(__file__)
sys.exit()
OR
os.startfile(sys.argv[0])
sys.exit()
答案 7 :(得分:0)
受@YumYumYum的启发并修复了问题 使用restart.sh和os.execl
restart.sh
#!/bin/bash/
pkill -f main.py
python main.py
将此添加到您的main.py
os.excel("restart.sh","")
答案 8 :(得分:0)
我正在使用它为用户提供一个选项,以便用户在控制台内重新启动脚本。希望对您有所帮助。
def close_restart(self,csvfile):
choice = input('Do you want to restart the program? Please select \'Y\' if you would like to restart.')
if choice == 'Y' or choice == 'y':
print('Restarting now...')
os.execl(sys.executable, sys.executable, *sys.argv)
else:
print('Thank you for using the tool!')
print('The program will close in 10s...')
time.sleep(10)
因此用户可以输入选项“是/否”来重新启动程序。
答案 9 :(得分:0)
我一直在寻找解决方案,但没有发现任何可用于任何堆栈溢出帖子的东西。也许某些答案太过时了,例如os.system已被子进程替换。我在使用python 3的linux lubuntu 17.10上。
两种方法对我有用。两者都打开一个新的Shell窗口并在其中运行main.py脚本,然后关闭旧的。
1。将main.py与.sh脚本一起使用。
改编自@YumYumYum方法。我不需要kill选项(尽管无论如何它都没有按名称杀死我的python进程,并且在测试时我不得不使用#!/bin/bash
lxterminal -e python3 /home/my/folder/main.py &
来实现它)。
我使用lxterminal,但是您可以使用任何一个。
在名为restart.sh的文件中(chmod + x使其可执行)
import subprocess
subprocess.run('/home/my/folder/restart.sh', shell=True)
quit()
然后在main.py中需要调用它时使用它
import subprocess, time
cmd = 'python3 /home/my/folder/main.py'
subprocess.run('lxterminal -e ' + cmd, shell=True)
time.sleep(0.2)
quit()
2。从main.py内部
改编自@Stuffe方法。该脚本位于main.py脚本的内部,并打开一个新的Shell窗口,然后运行新的脚本,然后退出旧脚本。我不确定它是否需要time.sleep延迟,但无论如何我还是用它。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://some.url.com"
android:layout_width="match_parent">
<include
layout="@layout/alarms_layout"
android:layout_width="wrap_content"
/>
<ImageView
android:id="@+id/saved_files"
android:layout_alignParentEnd="true"
/>
</RelativeLayout>