首頁  >  問答  >  主體

linux - 如何查看python脚本自动退出原因?

使用gunicorn+flask框架,同时通过apscheduler实现对一款爬虫的定时调用,但是在这其中遇到了一个问题,如下:
1,我利用shell终端,通过gunicorn -c直接运行,然后通过flask构造url调用爬虫,并在终端观察输出信息,可以完美调用爬虫。但是当我运行gunicorn -c之后,关闭终端,则爬虫不能完美运行,通过对爬虫调试,发现在运行一段时间后就被终止。
2,之后我在爬虫中使用os.system('nohup python spider.py &'),并且一直打开终端可以完美运行,但是在关闭终端的情况下,又无法执行到底。
所以请问大家怎么来看一下这个脚本运行中为何自动结束。或者说产生的原因是什么。

迷茫迷茫2741 天前1157

全部回覆(4)我來回復

  • ringa_lee

    ringa_lee2017-04-18 10:08:12

    你這個進程沒有脫離終端,終端關閉後,和終端關聯的所有子進程全被終止,沒有任何輸出。
    建議把spaider.py做成daemon進程,脫離終端的控制。

    回覆
    0
  • 阿神

    阿神2017-04-18 10:08:12

    記錄

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-18 10:08:12

    謝謝大家的答案,真正的原因已經找到,是因為由於調試過程的print輸出過多,導致超過緩存,導致進程結束。

    回覆
    0
  • 高洛峰

    高洛峰2017-04-18 10:08:12

    雖然你將進程放在後台執行,但是並沒有跟啟動該進程的終端detach,因此,父進程shell終端關閉,子進程也將被關閉。

    解決方案1,可以參考How to make a Python script run like a service or daemon in Linux,教你如何在linux下編程將進程做成daemon進程。範例程式比較長,我放在最後講解吧。

    解決方案2,有python函式庫可以將自身進程daemon化,而且還挺多的。比如,python-daemon。使用範例如下:

    import daemon
    
    def do_main_program():
        pass  # 你的程序
    
    with daemon.DaemonContext():
        do_main_program()
        

    補充解決方案1的處理:

    # -*- coding: utf-8 -*-
    import os
    import sys
    import datetime
    
    def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
        try:
            pid = os.fork()
            if pid > 0:
                sys.exit(0)  # Exit first parent.
        except OSError, e:
            sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
            sys.exit(1)
        # Decouple from parent environment.
        os.chdir("/")
        os.umask(0)
        os.setsid()
        # Do second fork.
        try:
            pid = os.fork()
            if pid > 0:
                sys.exit(0)  # Exit second parent.
        except OSError, e:
            sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
            sys.exit(1)
        # Redirect standard file descriptors.
        si = file(stdin, 'r')
        so = file(stdout, 'a+')
        se = file(stderr, 'a+', 0)
        os.dup2(si.fileno(), sys.stdin.fileno())
        os.dup2(so.fileno(), sys.stdout.fileno())
        os.dup2(se.fileno(), sys.stderr.fileno())
        
    if __name__ == "__main__":
        daemonize()
        # 然后开始执行你的其他程序。

    回覆
    0
  • 取消回覆