如何暂停在终端中运行的python脚本
我有一个在终端运行的网页爬虫Python脚本,已经运行了好几个小时,正在不断地往我的数据库里添加数据。这个脚本里面有好几个嵌套的循环。由于某些原因,我需要重启我的电脑,并且希望能从我停止的地方继续运行这个脚本。请问有没有办法保存当前的状态,然后在终端中恢复之前运行的脚本?
我希望找到一个解决方案,不需要修改Python脚本。因为如果要改代码,就得重新启动程序,还得花时间。
更新:谢谢你们的虚拟机建议。我会考虑这个。为了完整起见,应该对脚本做哪些通用的修改,以便让它可以暂停和恢复呢?
更新2:在虚拟机上运行效果很好。我还修改了脚本,使它在网络出现故障时也能安全运行。下面是我写的代码。
6 个回答
正如其他人所说的,如果你不是在一个可以暂停的虚拟机里运行你的脚本,那你就需要修改你的脚本来记录它的状态。
我把我的脚本移到了虚拟机上,并从那里启动了它。不过,在从休眠状态恢复后,网络连接出现了一些问题。以下是我通过调整Python脚本来解决这个问题的方法:
import logging
import socket
import time
socket.setdefaulttimeout(30) #set timeout in secs
maxretry = 10 #set max retries
sleeptime_between_retry = 1 #waiting time between retries
erroroccured = 0
while True:
try:
domroot = parse(urllib2.urlopen(myurl)).getroot()
except Exception as e:
erroroccured += 1
if erroroccured>maxretry:
logger.info("Maximum retries reached. Quitting this leg.")
break
time.sleep(sleeptime_between_retry)
logging.info("Network error occurred. Retrying %d time..."%(erroroccured))
continue
finally:
#common code to execute after try or except block, if any
pass
break
这个修改让我的脚本在网络出现故障时也能正常运行。
你可以试着让你的电脑进入休眠状态,或者在虚拟机里运行你的程序,这样你之后可以再恢复。不过,由于你的脚本在处理网络连接,所以当你重新启动系统时,脚本可能无法从你上次停止的地方继续运行。因为无论是让电脑休眠后恢复,还是保存虚拟机的状态再恢复,都意味着你需要重新建立网络连接。这对任何外部元素都是适用的,而网络就是其中之一。如果你使用的是动态网络,下次启动时很可能会得到一个新的IP地址,这样之前的网络状态就不再有效了。
如果你打算修改脚本,有几点需要注意:
- 添加序列化和反序列化的功能。Python有一个叫pickle的工具,还有一个更快的cPickle方法可以用来实现。
- 添加重启点。最好的方法是在定期保存状态,当你重新启动脚本时,从最后保存的状态开始,并在此之前建立所有临时元素,比如网络连接。
这并不是一件简单的事情,所以要考虑投入相当多的时间哦 :-)
注意***
再想想,其实还有一种替代方案,不用修改你的脚本。你可以尝试使用像亚马逊EC2这样的云虚拟化解决方案。