嵌入在Shell脚本中的Python脚本无法退出,守护进程解决方案不合适
这个问题是对之前一个问题的延续或重提。之所以重新提起这个话题,是因为之前的回答没有解决我遇到的同样问题。
这个bash脚本中嵌入了一个python脚本,类似于下面这样:
#!/bin/bash
./pyscript.py
我已经给这个脚本设置了执行权限,命令是 chmod +x pyscript.py
。
我还尝试了其他几种运行这个脚本的方法,比如用 python -u pyscript.py
或者 /usr/bin/python pyscript.py
。
正如标题所说,这个python程序并没有正常退出。
为了尝试解决这个问题,我在python脚本中做了以下几种尝试:
- 使用
sys.exit(0);
,这个方法能正确捕捉到异常。 - 使用
os._exit(1)
,这个方法不管用,虽然也能捕捉到正确的异常。 - 使用
sys.stdout.flush()
,这个是为了清理标准输出的缓存。
我不需要的解决方案是守护进程,因为它在后台独立运行,不会等到python程序执行完毕。
那么在这种情况下,还有哪些其他的解决方案呢?
4 个回答
另外,你可以试试 trace模块,也就是说,你可以用 #!/usr/bin/env python -m trace --trace
来运行你的程序。如果Python正在执行你的一些代码(很可能是这样),它会给你显示相关的详细信息。
我通常做的事情是把一个脚本放到一个叫做“screen”的会话里,这样它就和主终端分开了。然后我可以轻松地结束这个脚本的进程,不会有任何麻烦。不过在这个特定的情况下,我想让程序等到这个Python脚本执行完毕,而不是让它和主程序同时运行。
你有没有试过在 Python 进程上使用 strace -p $PID
呢?不过输出的结果不一定总是有用的。
从代码的角度来看,除了线程之外,我还会检查一下是否有信号处理程序(可能因为某些原因没有终止)。
关于线程,你可能会对 这个链接 感兴趣,虽然我记得之前有人在其他讨论中提到过这个问题。
最后问题解决了。
我一直想结束的这个Python程序是多线程运行的。sys.exit(0)
只会结束调用它的那个线程。
在执行之前,os._exit(1)
是和 sys.exit(0)
一起调用的(失败了!)。
如果先直接运行 os._exit(1)
,而不先调用 sys.exit(0)
,程序就会退出Python脚本。
原因可能是 sys.exit()
只结束它被调用的那个线程,并允许程序清理资源,而 os._exit()
则是直接强制结束程序。
找到的资料可以在 这里。
用这个方法可以更好地确保程序结束任何需要结束的任务,然后再调用 os._exit
。