
面试翻车现场面试过一个做机器人项目的候选人我问他你的机器人程序怎么实现开机自启他说在rc.local里加一行。我问如果程序崩溃了怎么自动重启他说写个脚本定期检查挂了就重新启动。我又问如果程序启动失败怎么收集日志排查问题他沉默了。rc.local是十年前的做法了。现代Linux系统用systemd管理服务功能强大得多。做机器人开发你的程序需要在机器人开机时自动启动、崩溃后自动重启、日志自动记录——这些systemd都能帮你搞定。systemd是什么systemd是Linux的系统和服务管理器。它是系统启动后运行的第一个进程PID 1负责启动和管理其他所有服务。Ubuntu 16.04之后默认使用systemd。你用的ROS2、Docker、SSH背后都是systemd在管理。基本命令systemctl status ssh # 查看服务状态 systemctl start ssh # 启动服务 systemctl stop ssh # 停止服务 systemctl restart ssh # 重启服务 systemctl enable ssh # 设置开机自启 systemctl disable ssh # 取消开机自启查看系统上所有服务systemctl list-units --typeservice # 列出所有正在运行的服务 systemctl list-unit-files --typeservice # 列出所有已安装的服务创建自定义服务让你的机器人程序开机自启需要创建一个service文件。sudo vim /etc/systemd/system/robot-node.service写入以下内容[Unit] DescriptionRobot Navigation Node Afternetwork.target [Service] Typesimple Userrobot WorkingDirectory/home/robot/robot_ws ExecStart/bin/bash -c source /opt/ros/humble/setup.bash source /home/robot/robot_ws/install/setup.bash ros2 run nav2_node nav2_node Restartalways RestartSec5 EnvironmentROS_DOMAIN_ID0 [Install] WantedBymulti-user.target各部分含义[Unit]服务的元数据和依赖关系。Afternetwork.target表示在网络就绪后启动。[Service]服务的具体配置。Typesimple表示主进程就是服务进程Userrobot指定运行用户ExecStart是启动命令Restartalways表示崩溃后自动重启RestartSec5表示重启前等待5秒。[Install]安装配置。WantedBymulti-user.target表示在多用户模式正常启动时启动。创建完后启用并启动服务sudo systemctl daemon-reload # 重新加载配置 sudo systemctl enable robot-node # 设置开机自启 sudo systemctl start robot-node # 立即启动 sudo systemctl status robot-node # 查看状态日志管理systemd自动收集服务的标准输出和标准错误用journalctl查看journalctl -u robot-node # 查看服务日志 journalctl -u robot-node -f # 实时跟踪日志 journalctl -u robot-node --since today # 查看今天的日志 journalctl -u robot-node -n 50 # 查看最后50行日志默认存储在/var/log/journal/目录下。如果日志太多占用磁盘空间可以配置日志轮转sudo vim /etc/systemd/journald.conf[Journal] SystemMaxUse500M # 日志最大占用500MB SystemMaxFileSize50M # 单个日志文件最大50MB MaxRetentionSec7day # 保留7天修改后重启journaldsudo systemctl restart systemd-journald和机器人开发的关系systemd在机器人开发中非常实用。几个典型场景机器人主控程序开机自启机器人上电后自动启动导航、感知等核心节点不需要人工干预。崩溃自动重启Restartalways确保程序崩溃后自动恢复提高系统可靠性。依赖管理Afternetwork.target确保网络就绪后再启动需要网络的节点。还可以用Requires声明硬性依赖。日志集中管理所有服务的日志统一用journalctl查看不用自己写日志系统。资源限制可以限制服务的CPU、内存使用[Service] CPUQuota50% # 最多使用50%的CPU MemoryMax1G # 最多使用1GB内存面试常见考点systemd和init有什么区别——systemd是现代Linux的初始化系统支持并行启动、服务依赖管理、日志收集等功能传统的SysVinit是串行启动功能简单。怎么让一个程序开机自启——创建systemd service文件配置ExecStart然后systemctl enable。服务启动失败怎么排查——用systemctl status查看状态和错误信息用journalctl -u查看详细日志。常见原因路径错误、权限不足、依赖服务未启动。Restartalways和Restarton-failure的区别——always无论什么原因退出都重启on-failure只在非正常退出退出码非0时重启。给你的建议systemd是Linux系统管理的核心工具做机器人开发必须掌握。把机器人的核心程序都配置成systemd服务实现开机自启和崩溃自动重启。这比写脚本定期检查靠谱得多。日志用journalctl查看不要自己写日志系统。systemd已经帮你做好了日志收集、轮转、持久化。遇到问题先看systemctl status和journalctl90%的问题都能从日志里找到答案。调试服务时可以临时把Restartno这样程序崩溃后不会自动重启方便你用gdbattach上去调试。调试完再改回Restartalways。systemd服务的编写实战在机器人项目中经常需要把某些程序设置为开机自启动比如传感器驱动或通信中间件。systemd的service文件写法其实不复杂关键是几个字段[Unit]定义依赖关系[Service]定义启动命令和重启策略[Install]定义安装方式。一个实用的模板是设置Restartalways和RestartSec5这样进程崩溃后会自动重启。面试时如果能写出一个完整的service文件会很有说服力。systemd timer替代cron的现代方案systemd不仅能管理长期运行的服务还能替代cron做定时任务。systemd timer比cron更强大——支持精确到秒的调度、可以和service联动、日志统一走journalctl。比如每小时清理机器人日志创建一个oneshot service配合timer文件就行用OnCalendarhourly设置调度Persistenttrue确保错过的任务在重启后补执行。用systemctl list-timers查看所有活跃的定时器。上一篇第92篇 环境变量与路径——ROS2开发中必须搞懂的基础概念下一篇预告第94篇 cron定时任务——机器人日志清理和数据定期备份