丁香医生 2025-10-19 21:45 采纳率: 99%
浏览 0
已采纳

rc.local在Ubuntu 20.04中如何正确启用与开机执行?

在Ubuntu 20.04中,由于系统已全面采用systemd,传统的`rc.local`机制默认被禁用,导致许多用户在尝试配置开机自启脚本时遇到问题。常见问题是:即使创建了`/etc/rc.local`文件并赋予执行权限,其中的命令仍无法在启动时运行。这通常是因为`rc-local.service`未启用或`rc.local`文件格式不正确(如缺少正确的shebang或退出语句)。如何正确配置`rc.local`服务,确保其在系统启动时被systemd识别并执行?
  • 写回答

1条回答 默认 最新

  • 蔡恩泽 2025-10-19 21:45
    关注

    1. 背景与问题引入

    在Ubuntu 20.04中,系统已全面采用systemd作为初始化系统,传统的rc.local机制默认被禁用。尽管许多管理员习惯于通过/etc/rc.local执行开机自启命令,但在新版本中即使创建了该文件并赋予执行权限,其中的脚本仍无法运行。

    根本原因在于:systemd不再自动加载rc.local,必须显式启用对应的rc-local.service单元,并确保脚本格式符合要求(如包含正确的shebang和退出码)。这一变化对运维人员提出了更高的系统理解要求。

    2. 常见问题分析

    • rc.local 文件存在但未执行:通常因为rc-local.service未启用或未正确配置。
    • 权限不足:缺少可执行权限(chmod +x /etc/rc.local)。
    • 语法错误:未添加#!/bin/bash或未以exit 0结尾。
    • 服务依赖缺失rc-local.service可能因网络、挂载等资源未就绪而失败。
    • 日志排查困难:用户未使用journalctl -u rc-local.service查看具体错误。

    3. 解决方案步骤详解

    1. 创建或编辑/etc/rc.local文件:
    sudo nano /etc/rc.local

    内容示例:

    #!/bin/bash
    # 开机自启脚本示例
    
    echo "Starting custom startup script at $(date)" >> /var/log/rc-local.log
    
    # 示例命令:挂载NFS、启动守护进程等
    # mount -t nfs server:/share /mnt/nfs
    # /opt/mydaemon --start
    
    exit 0
    1. 赋予执行权限:
    sudo chmod +x /etc/rc.local
    1. 检查rc-local.service是否存在:
    systemctl status rc-local

    若提示“not found”,需手动创建服务单元文件。

    4. 手动创建 systemd 服务单元

    字段说明
    [Unit]定义服务元信息及依赖关系
    Description服务描述
    After指定启动顺序,确保基础系统已准备就绪
    [Service]服务执行配置
    Type设置为forking以兼容传统rc.local行为
    ExecStart指向实际执行的脚本路径
    TimeoutSec避免长时间阻塞启动过程
    [Install]定义如何启用服务

    创建服务文件:

    sudo nano /etc/systemd/system/rc-local.service

    内容如下:

    [Unit]
    Description=/etc/rc.local Compatibility
    ConditionPathExists=/etc/rc.local
    After=network.target
    
    [Service]
    Type=forking
    ExecStart=/etc/rc.local start
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    SyslogIdentifier=rc-local
    
    [Install]
    WantedBy=multi-user.target

    5. 启用并验证服务状态

    1. 重载systemd配置:
    sudo systemctl daemon-reexec
    sudo systemctl daemon-reload
    1. 启用并启动服务:
    sudo systemctl enable rc-local
    sudo systemctl start rc-local
    1. 检查服务状态与日志:
    sudo systemctl status rc-local
    sudo journalctl -u rc-local.service --since "1 hour ago"

    6. 高级调试与替代方案建议

    graph TD A[系统启动] --> B{rc-local.service 是否启用?} B -- 是 --> C[执行 /etc/rc.local] B -- 否 --> D[跳过传统脚本] C --> E[检查 exit code] E --> F{成功?} F -- 是 --> G[继续启动流程] F -- 否 --> H[记录错误到 journald] H --> I[管理员通过 journalctl 排查] I --> J[修复脚本或依赖]

    对于现代系统,推荐逐步迁移至原生systemd服务单元,而非依赖兼容层。例如,将长期运行的后台程序封装为独立的.service文件,实现更精细的控制(如重启策略、资源限制、依赖管理)。

    此外,可通过systemd-analyze plot > boot.svg生成启动时序图,分析rc-local在整体启动流程中的位置与耗时影响。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 10月20日
  • 创建了问题 10月19日