i.MX6 Yocto系统启动时后台脚本随父进程终止问题求助
这是个典型的systemd环境下子进程被意外回收的问题,我来帮你拆解原因并给出可行的解决办法:
问题根源
当你通过systemd的custom-script.service启动脚本时,systemd会将整个服务相关的进程纳入一个**控制组(cgroup)**管理。默认情况下,当服务的主进程(这里是运行custom-script的/bin/sh进程)退出后,systemd会清理这个控制组内的所有进程——包括a.sh以及它后台启动的b.sh。这就是为什么a.sh运行结束后,b.sh也被终止的原因。
而手动启动时,a.sh和b.sh属于你的终端shell的进程组,systemd不会干预它们的生命周期,所以b.sh能正常运行到结束。
解决方案
方案1:修改systemd服务配置(最可靠)
修改/lib/systemd/system/custom-script.service的[Service]段,添加KillMode=process配置,让systemd只终止主进程,不清理子进程:
[Unit] Description=start custom script at boot [Service] Type=simple ExecStart=/bin/sh -c '/usr/bin/custom-script' KillMode=process # 新增这一行 [Install] WantedBy=multi-user.target
修改后,重新加载systemd配置并重启服务:
systemctl daemon-reload systemctl restart custom-script.service
方案2:让b.sh脱离父进程组控制
如果不想修改systemd服务,也可以修改a.sh中启动b.sh的命令,让它彻底脱离a.sh的进程组和shell的作业控制:
# 替换a.sh中的/mnt/tmp/b.sh & 为以下命令 nohup /mnt/tmp/b.sh >/dev/null 2>&1 & disown
nohup:让进程忽略SIGHUP信号(父进程退出时发送的终止信号)>/dev/null 2>&1:重定向输出到空设备,避免生成nohup.out文件disown:将进程从shell的作业列表中移除,让它不受shell退出的影响
方案3:将b.sh注册为独立systemd服务(更规范)
如果b.sh需要长期运行,更推荐直接为它创建独立的systemd服务,比如b-script.service:
[Unit] Description=Run b.sh script After=custom-script.service [Service] Type=simple ExecStart=/mnt/tmp/b.sh Restart=no [Install] WantedBy=multi-user.target
然后启用服务:
systemctl daemon-reload systemctl enable b-script.service
这样b.sh会在custom-script启动后独立运行,不受其他进程影响。
验证方法
修改完成后重启系统,查看/tmp/b.sh.log是否能记录到0-9秒的日志,确认b.sh能正常运行到结束。
内容的提问来源于stack exchange,提问作者azeddine ben omar

