嵌入在Shell脚本中的Python脚本无法退出,守护进程解决方案不合适

3 投票
4 回答
2490 浏览
提问于 2025-04-21 03:33

这个问题是对之前一个问题的延续或重提。之所以重新提起这个话题,是因为之前的回答没有解决我遇到的同样问题。

这个bash脚本中嵌入了一个python脚本,类似于下面这样:

  #!/bin/bash
  ./pyscript.py 

我已经给这个脚本设置了执行权限,命令是 chmod +x pyscript.py

我还尝试了其他几种运行这个脚本的方法,比如用 python -u pyscript.py 或者 /usr/bin/python pyscript.py

正如标题所说,这个python程序并没有正常退出。

为了尝试解决这个问题,我在python脚本中做了以下几种尝试:

  1. 使用 sys.exit(0);,这个方法能正确捕捉到异常。
  2. 使用 os._exit(1),这个方法不管用,虽然也能捕捉到正确的异常。
  3. 使用 sys.stdout.flush(),这个是为了清理标准输出的缓存。

我不需要的解决方案是守护进程,因为它在后台独立运行,不会等到python程序执行完毕。

那么在这种情况下,还有哪些其他的解决方案呢?

4 个回答

0

另外,你可以试试 trace模块,也就是说,你可以用 #!/usr/bin/env python -m trace --trace 来运行你的程序。如果Python正在执行你的一些代码(很可能是这样),它会给你显示相关的详细信息。

0

我通常做的事情是把一个脚本放到一个叫做“screen”的会话里,这样它就和主终端分开了。然后我可以轻松地结束这个脚本的进程,不会有任何麻烦。不过在这个特定的情况下,我想让程序等到这个Python脚本执行完毕,而不是让它和主程序同时运行。

1

你有没有试过在 Python 进程上使用 strace -p $PID 呢?不过输出的结果不一定总是有用的。

从代码的角度来看,除了线程之外,我还会检查一下是否有信号处理程序(可能因为某些原因没有终止)。

关于线程,你可能会对 这个链接 感兴趣,虽然我记得之前有人在其他讨论中提到过这个问题。

1

最后问题解决了。

我一直想结束的这个Python程序是多线程运行的。sys.exit(0) 只会结束调用它的那个线程。

在执行之前,os._exit(1) 是和 sys.exit(0) 一起调用的(失败了!)。

如果先直接运行 os._exit(1),而不先调用 sys.exit(0),程序就会退出Python脚本。

原因可能是 sys.exit() 只结束它被调用的那个线程,并允许程序清理资源,而 os._exit() 则是直接强制结束程序。

找到的资料可以在 这里

用这个方法可以更好地确保程序结束任何需要结束的任务,然后再调用 os._exit

撰写回答