面试翻车现场

面试过一个候选人,我问他:"你的机器人每天产生几个GB的日志,磁盘满了怎么办?"

他说:"手动清理。"

我问:"如果机器人部署在客户现场,没人维护呢?"

他说:"那就……定期去看看?"

这就是缺乏自动化思维。生产环境的机器人必须能自我管理——日志自动清理、数据定期备份、系统健康检查。这些都可以用cron定时任务来实现。

cron是什么

cron是Linux的定时任务调度器。它可以按照你设置的时间间隔,自动执行指定的命令。

cron的配置文件叫crontab。每个用户都可以有自己的crontab。

crontab基本用法

crontab -e          # 编辑当前用户的crontab
crontab -l          # 列出当前用户的定时任务
crontab -r          # 删除当前用户的所有定时任务

第一次运行crontab -e会让你选择编辑器,选nano或vim都行。

cron表达式

cron表达式由5个时间字段和1个命令字段组成:

* * * * * command
│ │ │ │ │
│ │ │ │ └── 星期几 (0-7, 0和7都是周日)
│ │ │ └──── 月份 (1-12)
│ │ └────── 日期 (1-31)
│ └──────── 小时 (0-23)
└────────── 分钟 (0-59)

常用示例:

# 每天凌晨2点执行
0 2 * * * /path/to/script.sh

# 每5分钟执行一次
*/5 * * * * /path/to/script.sh

# 每小时执行一次
0 * * * * /path/to/script.sh

# 每周一上午9点执行
0 9 * * 1 /path/to/script.sh

# 每月1号凌晨3点执行
0 3 1 * * /path/to/script.sh

特殊字符:

  • *:每个(任意值)
  • ,:列表(1,3,5表示1、3、5)
  • -:范围(1-5表示1到5)
  • /:步长(*/5表示每5个单位)

实战:机器人日志清理

机器人每天产生大量日志,磁盘很快就会被撑满。用cron定期清理:

crontab -e

添加以下任务:

# 每天凌晨3点清理7天前的日志
0 3 * * * find /home/robot/robot_logs -name "*.log" -mtime +7 -delete

# 每周日凌晨4点清理30天前的rosbag数据
0 4 * * 0 find /home/robot/bags -name "*.db3" -mtime +30 -delete

find命令的参数:-name匹配文件名,-mtime +7表示修改时间超过7天,-delete删除匹配的文件。

更安全的做法是先移到临时目录,确认无误后再删除:

# 每天凌晨3点把7天前的日志移到/tmp/old_logs
0 3 * * * find /home/robot/robot_logs -name "*.log" -mtime +7 -exec mv {} /tmp/old_logs/ \;

实战:数据定期备份

机器人的配置文件、标定数据、地图文件很重要,需要定期备份。

创建备份脚本/home/robot/scripts/backup.sh:

#!/bin/bash
BACKUP_DIR="/home/robot/backups"
DATE=$(date +%Y%m%d_%H%M%S)

# 创建备份目录
mkdir -p $BACKUP_DIR

# 备份配置文件和地图
tar -czf $BACKUP_DIR/robot_config_$DATE.tar.gz \
    /home/robot/robot_ws/src/*/config/ \
    /home/robot/maps/

# 只保留最近7天的备份
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete

echo "备份完成:$BACKUP_DIR/robot_config_$DATE.tar.gz"

添加执行权限:

chmod +x /home/robot/scripts/backup.sh

设置cron定时执行:

# 每天凌晨2点备份
0 2 * * * /home/robot/scripts/backup.sh >> /home/robot/logs/backup.log 2>&1

>> /home/robot/logs/backup.log 2>&1把标准输出和标准错误都追加到日志文件,方便排查问题。

实战:系统健康检查

定期检查机器人的系统状态,发现问题及时告警:

创建脚本/home/robot/scripts/health_check.sh:

#!/bin/bash

# 检查磁盘空间
DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $DISK_USAGE -gt 90 ]; then
    echo "警告:磁盘使用率超过90%!当前:${DISK_USAGE}%"
fi

# 检查内存使用
MEM_USAGE=$(free | awk 'NR==2 {printf "%.0f", $3/$2*100}')
if [ $MEM_USAGE -gt 90 ]; then
    echo "警告:内存使用率超过90%!当前:${MEM_USAGE}%"
fi

# 检查关键进程是否运行
if ! pgrep -x "robot_node" > /dev/null; then
    echo "警告:robot_node进程未运行!"
fi

设置cron定时检查:

# 每10分钟检查一次
*/10 * * * * /home/robot/scripts/health_check.sh >> /home/robot/logs/health.log 2>&1

cron的注意事项

环境变量问题:cron执行的环境变量和你的shell不一样。PATH可能不包含你的自定义路径。解决方法是在脚本里用绝对路径,或者在crontab开头设置环境变量:

PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash

0 2 * * * /home/robot/scripts/backup.sh

输出问题:cron任务的输出默认会通过邮件发送给用户。如果没配置邮件,输出会被丢弃。建议把输出重定向到日志文件。

权限问题:cron以当前用户身份执行任务。如果需要root权限,用sudo crontab -e编辑root的crontab,或者在脚本里用sudo(需要配置免密码)。

时区问题:cron使用系统时区。检查时区:timedatectl。修改时区:sudo timedatectl set-timezone Asia/Shanghai。

面试常见考点

"cron表达式*/5 * * * *是什么意思?"——每5分钟执行一次。*/5在分钟字段表示每5分钟。

"怎么查看cron任务的执行日志?"——查看/var/log/syslog(Ubuntu)或/var/log/cron(CentOS),或者把任务输出重定向到自定义日志文件。

"cron和systemd timer有什么区别?"——cron是传统的定时任务工具,配置简单;systemd timer是现代替代方案,功能更强大(支持随机延迟、依赖管理等),但配置复杂。简单定时任务用cron,复杂场景用systemd timer。

"cron任务不执行怎么排查?"——检查cron服务是否运行(systemctl status cron);检查crontab语法是否正确;检查脚本是否有执行权限;检查环境变量和路径问题;查看cron日志。

cron与定时任务的工程实践

在机器人项目中,cron常用于定时数据采集和日志清理。一个典型的用法是每天凌晨自动备份机器人的地图数据和配置参数。写cron任务时要注意环境变量问题,cron执行时的环境变量和用户登录时不同,所以脚本里要用绝对路径。另外/etc/cron.daily/目录下的脚本会自动每天执行,比手写cron表达式更方便。

给你的建议

cron是Linux系统管理的基础工具,做机器人开发必须掌握。

把日志清理、数据备份、健康检查这些重复性工作都交给cron。你的机器人应该能自我管理,不需要人工干预。

写cron脚本时注意:用绝对路径;把输出重定向到日志文件;考虑环境变量问题;测试脚本能正常运行后再加到crontab。

几个实用的cron任务建议:每天清理旧日志、每周备份配置和地图、每小时检查系统状态。这些能帮你避免很多生产环境的问题。


上一篇:第93篇 systemd服务管理——让机器人程序开机自启

下一篇预告:第95篇 SSH远程开发——连接机器人本体调试的标配方式

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐