脚本跑起来就撒手不管?用 systemd 把它变成开机自启的服务
写了个小脚本,手动跑起来没问题,机器一重启就没了;进程挂了没人知道,只能等用户先发现。这种“裸跑”的脚本迟早会出一次让你半夜爬起来的故障。systemd 就是系统自带的进程管家:把脚本包成一个服务,交给它管开机自启、挂了自动拉起来、日志统一收,基本功一次写好能省很多事。
一、一个服务文件只有三段
在 /etc/systemd/system/ 下面新建一个以 .service 结尾的文件,比如 myjob.service,内容分三段。Unit 段写描述和依赖,After=network.target 表示等网络就绪再启动;Service 段是核心,ExecStart 写启动命令,必须用绝对路径,Type=simple 适合前台常驻的进程,Restart=always 表示退出就自动重启;Install 段写 WantedBy=multi-user.target,表示开机进入多用户模式时启动它。
写完之后 systemctl daemon-reload 重新加载配置,systemctl enable myjob 设为开机自启,systemctl start myjob 立即启动。三个命令的顺序别错:不 reload,systemd 根本不知道新文件存在。
二、重启策略要按需选
Restart 不是只有 always 一个选项。on-failure 只在异常退出时重启,适合跑批处理、定时任务这类正常退出就不该再跑的程序;always 连正常退出也重启,适合常驻服务。配合 RestartSec=5 给个几秒间隔,避免程序一启动就崩、systemd 疯狂拉起形成重启风暴。
还有两个容易忽略的字段:WorkingDirectory 指定工作目录,脚本里用相对路径读配置、写文件时全靠它;User 指定运行用户,别图省事都用 root 跑,能用普通用户就用普通用户,权限最小化出事也小。
三、日志就地查,不用自己写轮转
服务一旦交给 systemd,标准输出和标准错误自动进 journal,不用再在脚本里自己写日志文件、自己做轮转。journalctl -u myjob 看这个服务的日志,-f 实时跟,--since today 只看今天的。日志默认存在内存或磁盘的 journal 里,量大了会自动清理,比散落在各处的 nohup.out 好找得多。
状态查询也一样集中:systemctl status myjob 一眼看到是否在跑、最近一次启动时间、最近几行日志;systemctl is-enabled myjob 确认开机自启有没有开。排障时先看 status,再看 journal,基本就够定位八成问题。
四、几个容易踩的小坑
一是 ExecStart 里不能直接写管道和重定向,systemd 不经过 shell 解析。需要管道就包一层 bash -c,或者把复杂逻辑写回脚本里,让 ExecStart 只调脚本。
二是环境变量不继承你的登录 shell。脚本在终端里跑得好好的,放进服务就报找不到命令,十有八九是 PATH 不一样。解决办法是在 Service 段用 Environment=写清楚,或者在脚本开头把需要的路径写成绝对路径。
三是改了服务文件一定要 daemon-reload,否则 systemd 用的还是旧版本。很多人改完配置直接 restart,发现行为没变,就是漏了这一步。
小结
判断标准很简单:只要一个脚本你希望它“机器重启还在、挂了自己回来、日志有地方查”,就别裸跑,花五分钟写个 service 文件交给 systemd。写文件、reload、enable、start 四步做完,半夜的告警就少一半。
(本文为个人运维实践记录。)
- 点赞
- 收藏
- 关注作者
评论(0)