如何暂停在终端中运行的python脚本

时间:2011-12-25 17:08:05

标签: python terminal pausing-execution

我在终端上运行了几个小时的网络抓取python脚本,这会不断填充我的数据库。它有几个嵌套的for循环。出于某些原因,我需要重新启动计算机并从我离开的地方继续我的脚本。是否可以保留指针状态并恢复以前在终端中运行的脚本?

我正在寻找一种可以在不改变python脚本的情况下工作的解决方案。修改代码的优先级较低,因为这意味着重新启动程序并重新投入时间。

更新: 感谢VM的建议。我会接受的。为了完成,应该对脚本进行哪些通用修改以使其暂停和恢复?

UPDATE2 : 在VM上移植工作正常。我还修改了脚本,使其能够对网络故障进行故障保护。代码如下。

6 个答案:

答案 0 :(得分:4)

您可以尝试暂停计算机或在随后可以暂停的虚拟机中运行。但是,由于您的脚本正在使用网络连接,因此一旦启动系统,您的脚本将无法从您离开的位置开始工作。暂停计算机并将其恢复或保存虚拟M / C并恢复它意味着您需要重新建立网络连接。对于系统外部的任何元素都是如此,网络就是其中之一。并且很有可能如果你使用动态网络,下次启动时你会得到一个新的IP,你之前工作的网络状态将是无效的。

如果您打算修改脚本,那么您需要记住一些事情。

  1. 添加序列化和反序列化功能。 Python有pickle和更快的cPickle方法。
  2. 添加重启点。执行此操作的最佳方法是定期保存状态,并在重新启动脚本时,在建立所有瞬态元素(如网络)后从上次保存的状态重新启动。
  3. 这不是一件容易的事,所以考虑投入大量的时间: - )

    请注意***

    再想一想。更改脚本有一种替代方法。您可以尝试使用Amazon EC2等云虚拟化解决方案。

答案 1 :(得分:1)

正如其他人所评论的那样,除非您在可以暂停的虚拟机中运行脚本,否则您需要修改脚本以跟踪其状态。

答案 2 :(得分:1)

由于您使用数据填充数据库,我建议使用它作为跟踪脚本进度的方法(获取解析的最新URL,列出待处理的URL等)。

如果脚本突然终止,您不必担心保存其状态,因为数据库事务将会解决,并且只保存您提交的数据。

当脚本被重新启动时,只会存储您完全处理过的URL的数据,并且您可以根据数据库继续获取下一个URL。

答案 3 :(得分:1)

我将我的脚本移植到VM并从那里启动它。但是,从休眠状态恢复后会出现网络连接故障。这是我通过调整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

此修改使我的脚本能够证明网络故障。

答案 4 :(得分:0)

如果此问题非常重要,可以保证这种财务投资,则可以在虚拟机上运行该脚本。需要关闭时,挂起虚拟机,然后关闭计算机。如果要重新启动,请启动计算机,然后唤醒虚拟机。

答案 5 :(得分:0)

WinPDB是一个支持远程调试的python调试器。我从来没有使用它,也不知道远程调试正在运行的进程是否需要修改脚本(这很可能,否则会出现安全问题);但是如果可以在不修改脚本的情况下进行远程调试,那么您可以将脚本的当前状态转储到文件中,并稍后确定如何加载它。我认为它不会起作用。