Python 守护进程实现指南:脚本后台常驻与脱离终端控制

落日邮差
落日邮差
发布时间:2026-10-12| 2人浏览过
原创

本文详解如何通过标准库在 Python 中编写守护进程。借助双重 Fork 机制、会话创建、目录切换与标准流重定向,使脚本彻底脱离终端控制实现后台持久运行,附带完整实现代码及日志验证方法。

目标:让 Python 脚本脱离终端持久后台运行

在日常服务端开发中,直接通过终端执行的脚本受限于 Shell 环境。一旦执行 Ctrl+C 或关闭终端,进程便会中断。为实现类似 httpd 或 mysqld 的常驻后台效果,需要将其改造为守护进程(英文 Daemon,程序名末尾通常带 d 即代表 Daemon)。

准备条件

具备基础 Python 运行环境即可。示例代码依赖内置 os、sys、time、threading 模块,无需安装第三方库。

实现步骤与核心逻辑

第1步:父进程退出,子进程脱离终端接管

目的:切断进程与原 Shell 环境的父子关联。原 Shell 结束执行后,产生的子进程将被系统 init 进程接管,从而不再受终端生命周期限制。

第2步:初始化运行环境

目的:防止因继承父目录导致磁盘无法卸载,并清除终端依赖。

  • 设置工作目录:os.chdir("/")
  • 创建新会话并成为组长:os.setsid()(彻底脱离控制终端)
  • 重置权限掩码:os.umask(0)(避免新创建的文件继承受限权限)

第3步:二次 Fork 生成孙子进程

目的:经过前两步,当前进程已成为新进程组的组长。为防止其意外重新申请打开终端,需再次调用 os.fork(),让当前的子进程立即退出,由孙子进程继续后续逻辑。此时孙子进程已完全独立于任何会话组。

第4步:重定向标准输入/输出/错误流

目的:守护进程已无交互需求。将 stdin、stdout、stderr 全部指向 /dev/null,丢弃无关输出,避免占用终端资源或产生脏数据。

完整代码实现

以下为结合上述流程封装的 Python 守护进程模板。核心业务逻辑位于 run() 函数内,本例以周期性发起网络请求并记录日志为例:

#!/usr/bin/env python
#coding=utf8
import os, sys, time, threading

def createDaemon():
    # 第一次 fork:父进程退出,子进程被 init 接管
    try:
        pid = os.fork()
        if pid > 0:
            sys.exit(0)
    except OSError as e:
        sys.exit(1)

    # 修改工作目录,创建新会话,调整 umask
    os.chdir("/")
    os.setsid()
    os.umask(0)

    # 第二次 fork:子进程退出,孙子进程成为真正守护进程
    try:
        pid = os.fork()
        if pid > 0:
            print("Daemon PID %d" % pid)
            sys.exit(0)
    except OSError as e:
        sys.exit(1)

    run()

def ping_task():
    # 模拟后台任务:发起 ping 请求
    os.system('ping www.baidu.com >/dev/null 2>&1')

def run():
    log_path = '/tmp/ping_daemon.log'
    while True:
        with open(log_path, 'a') as fd:
            fd.write(f"start time---------:{time.ctime()}\n")
            t = threading.Thread(target=ping_task)
            t.start()
            t.join()  # 确保线程完成任务后再计时,避免并发堆积
            fd.write(f"end of time--------:{time.ctime()}\n")
            fd.flush()
        time.sleep(3)

if __name__ == '__main__':
    createDaemon()
终端执行脚本后返回命令行,进程转入后台运行状态
执行脚本后终端立即返回提示符,表明主进程已成功转入后台运行。

从终端表现可见,指令发出后控制台未卡死,说明父进程已退出释放了终端占用。由于脱离了 Shell 管理,此类进程需使用 killall 或根据 PID 手动终止。

完成判断与排错验证

确认守护进程是否生效

  1. 进程隔离检查:后台运行期间,直接关闭 SSH 终端或断开连接,再次登录查看服务是否仍在运行(可通过 ps aux | grep your_script.py 验证)。
  2. 日志文件核对:守候进程会自动轮询执行任务并追加写入日志。
定时生成的日志文件内容截图,显示每次循环的时间戳记录
日志文件按间隔成功记录开始与结束时间戳,证明守护进程已稳定持续运行。

常见异常排查

  • 权限拒绝(Permission denied):若绑定特定端口或写入非用户目录,请使用 sudo 运行或提前修改文件夹权限。
  • 进程僵尸态:若发现多次运行后残留旧进程,请检查 sys.exit(0) 是否在所有分支正确触发,确保父/子进程均能正常收尾。

总结

利用 Python 标准库即可完成轻量级守护进程的构建。掌握“两次 Fork + 会话创建 + 流重定向”的组合拳,即可让任意长驻脚本脱离终端束缚。实际部署大型服务时,建议结合 Systemd 或 Supervisor 等进程管理器进行更完善的监控与重启配置。以上就是 Python 守护进程实现教程的详细内容,更多关于 Python 自动化运维与后台服务优化的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。