Linux 系统服务 systemd 入门:让脚本开机自启
很多新手第一次部署脚本时,习惯用 nohup 加 & 把进程挂在后台,或者写一条 @reboot 的 cron。机器一重启,进程经常起不来;进程挂了,也没有人自动拉起;日志散落在各处,出问题很难定位。Linux 系统上更稳妥的做法,是把脚本交给 systemd 管理:写一个服务单元,让系统在开机时按顺序启动它,挂了自动重启,日志统一进 journal。
一、先准备一个可独立运行的脚本
以一个最简单的定时写日志脚本为例,放在 /opt/hello/hello.sh,内容是每 30 秒向日志文件追加一行时间。脚本开头用 #!/bin/bash,关键是只用绝对路径,不要依赖当前目录和交互式环境。写好后执行 chmod +x /opt/hello/hello.sh,并先手动跑一次,确认它在前台也能正常输出、正常退出。手动都跑不通的脚本,交给 systemd 也不会变好,这一步不要跳过。
二、写一个服务单元文件
在 /etc/systemd/system/ 下新建 hello.service,结构分为三段。Unit 段写服务描述和启动顺序,例如 Description=Hello demo service,After=network.target 表示尽量在网络就绪后再启动。Service 段是核心:Type=simple 表示前台运行,ExecStart 写脚本的绝对路径,WorkingDirectory 指定工作目录,User 指定运行用户,不要图省事长期用 root。Restart=on-failure 表示异常退出时自动重启,RestartSec=5 表示隔 5 秒再试,避免瞬间反复重启把系统拖垮。Install 段写 WantedBy=multi-user.target,表示开机进入多用户模式时启用它。
三、启用、启动并验证
写好单元文件后,依次执行:systemctl daemon-reload,让 systemd 重新读取配置;systemctl enable hello,把它设为开机自启;systemctl start hello,立即启动一次;systemctl status hello,查看是否 active;systemctl is-enabled hello,确认显示 enabled。用 journalctl -u hello -f 可以实时看日志,排错时比到处找日志文件方便得多。验证开机自启最直接的办法,是重启一次机器,再用 status 和日志确认服务自己起来了,而不是只在当前会话里活着。
四、常见坑与排错思路
第一是路径问题:ExecStart、脚本里的相对路径、找不到的命令,都会导致启动失败,统一改成绝对路径最省事。第二是环境变量:systemd 的环境和登录 Shell 不一样,PATH、数据库连接串等不要默认继承,必要时在 Service 段用 Environment= 显式声明。第三是 Type 选错:如果脚本本身会 fork 到后台,就不要用 simple,否则 systemd 会误判主进程已退出。第四是权限:日志目录、数据目录的属主,要和 User 指定的用户一致,否则服务会反复启动失败。第五是依赖:如果服务依赖数据库或网络端口,除了 After,还要考虑 Wants 或 Requires,避免依赖还没准备好就反复报错。
五、日常管理命令
停止用 systemctl stop hello,重启用 systemctl restart hello,不再需要开机自启时用 systemctl disable hello,改了单元文件后先 daemon-reload 再 restart。查看最近日志用 journalctl -u hello --since today,查看启动失败原因先看 status 的最后几行,再看 journal,通常都能定位到是配置、权限还是脚本本身的问题。
小结:把脚本变成 systemd 服务,并不是多写几行配置,而是把“开机自启、异常重启、统一日志”交给系统去保证。先让脚本手动跑通,再写单元、启用、重启验证,这套流程跑通一次,以后任何常驻脚本都可以照着复用。
- 点赞
- 收藏
- 关注作者
评论(0)