工控必备Shell脚本开发:自动挂载、日志归档、看门狗、程序守护脚本
发布时间:2026/7/24 2:02:46
分类:文化教育
浏览:1234

工控必备Shell脚本开发自动挂载、日志归档、看门狗、程序守护脚本工控设备没有人在旁边盯着出问题得自己修自己扛。Shell脚本就是工控系统的瑞士军刀——挂磁盘、管日志、喂狗、保活一个脚本搞定一个活。一、Shell脚本在工控中的重要性工控设备部署在现场无人值守。U盘插上去要自动挂载日志满了要自动归档程序崩了要自动重启系统卡死要看门狗强制恢复——这些活全靠Shell脚本干。Shell脚本的优势无需编译、直接运行、依赖极少。工控板资源有限装Python解释器可能都嫌重但busybox自带ash/sh任何Linux板子都能跑Shell。二、脚本基础语法速查写工控脚本不需要精通Shell所有特性掌握以下核心语法足矣2.1 变量与条件#!/bin/bash# 变量赋值等号两边不能有空格DEVICE_PORT/dev/ttyS0BAUD_RATE115200# 条件判断if[-e$DEVICE_PORT];thenecho串口设备存在elseecho串口设备不存在exit1fi# 数值比较if[$BAUD_RATE-gt9600];thenecho高速串口fi# 字符串比较if[$MODEdebug];thenecho调试模式fi2.2 循环与函数# for循环遍历forportin/dev/ttyS{0..3};doecho检查端口:$portdone# while循环count0while[$count-lt10];doecho计数:$countcount$((count1))done# 函数定义check_process(){localname$1ifpgrep-x$name/dev/null;thenreturn0# 存活elsereturn1# 不存在fi}2.3 关键注意事项变量引用必须加双引号$VAR防止空值导致语法错误脚本头部加set -e遇到错误立即退出不让脚本带着错误继续跑比较用[ ]时运算符和值之间必须有空格三、实战脚本1U盘/SD卡自动挂载工控设备经常需要从U盘或SD卡读取配置文件、更新程序。手动挂载不现实脚本自动检测并挂载。#!/bin/bash# auto_mount.sh - U盘/SD卡自动挂载脚本set-eMOUNT_POINT/mnt/usbLOG_FILE/var/log/auto_mount.loglog_msg(){echo[$(date%Y-%m-%d %H:%M:%S)]$1$LOG_FILE}# 检测可移动存储设备find_usb_device(){fordevin/dev/sd{a,b,c}{1,2,3};doif[-b$dev];then# 检查是否已在挂载if!mountpoint-q$MOUNT_POINT;thenecho$devreturn0fifidonereturn1}# 挂载设备mount_device(){localdev$1mkdir-p$MOUNT_POINT# 尝试挂载支持常见文件系统ifmount-tvfat,ext4,ntfs-3g$dev$MOUNT_POINT2/dev/null;thenlog_msg挂载成功:$dev-$MOUNT_POINTreturn0elselog_msg挂载失败:$devreturn1fi}# 安全卸载umount_device(){ifmountpoint-q$MOUNT_POINT;thensync# 先刷新缓冲区umount$MOUNT_POINTlog_msg卸载完成:$MOUNT_POINTfi}# 主逻辑DEVICE$(find_usb_device)if[-n$DEVICE];thenmount_device$DEVICEelselog_msg未检测到可挂载设备fi配合udev规则可实现真正的插上即挂载# /etc/udev/rules.d/85-usb-mount.rulesACTIONadd,KERNELsd[a-z][1-9],RUN/usr/local/bin/auto_mount.shACTIONremove,KERNELsd[a-z][1-9],RUN/usr/local/bin/auto_umount.sh四、实战脚本2日志归档脚本工控程序24小时运行日志文件持续增长磁盘迟早撑爆。归档脚本按日期分割、压缩旧日志、自动清理过期文件。#!/bin/bash# log_archive.sh - 日志归档与自动清理脚本set-eLOG_DIR/var/log/appARCHIVE_DIR/var/log/app/archiveMAX_ARCHIVE_DAYS30# 保留30天归档MAX_LOG_SIZE_MB100# 单个日志文件超过100MB就归档mkdir-p$ARCHIVE_DIR# 获取当前日期标签DATE_TAG$(date%Y%m%d)# 扫描日志目录归档大文件forlog_filein$LOG_DIR/*.log;do[-f$log_file]||continue# 检查文件大小KB为单位file_size_kb$(du-k$log_file|cut-f1)file_size_mb$((file_size_kb/1024))if[$file_size_mb-ge$MAX_LOG_SIZE_MB];then# 归档拷贝压缩清空原文件archive_name$(basename$log_file.log)_${DATE_TAG}.log.gzcp$log_file${ARCHIVE_DIR}/${DATE_TAG}_tmpgzip-c${ARCHIVE_DIR}/${DATE_TAG}_tmp${ARCHIVE_DIR}/${archive_name}rm${ARCHIVE_DIR}/${DATE_TAG}_tmp# 清空原日志文件不是删除进程还在写truncate-s0$log_file2/dev/null||\$log_file# truncate不可用时用重定向清空echo[$(date)] 归档完成:$log_file(${file_size_mb}MB)fidone# 清理过期归档find$ARCHIVE_DIR-name*.log.gz-mtime$MAX_ARCHIVE_DAYS-deleteecho[$(date)] 过期归档清理完成${MAX_ARCHIVE_DAYS}天关键细节用truncate或重定向清空日志而不是删除文件因为进程仍然持有文件描述符——删了文件进程还在往幽灵文件里写磁盘空间照涨不误。五、实战脚本3看门狗喂狗脚本看门狗是工控系统的最后防线——软件卡死时看门狗超时触发硬件复位强制重启系统。喂狗就是告诉看门狗我还活着。#!/bin/bash# watchdog_feed.sh - 看门狗喂狗脚本set-eWDOG_DEVICE/dev/watchdogFEED_INTERVAL10# 每10秒喂一次看门狗超时通常设30秒MAX_FEED_RETRIES3# 检查看门狗设备是否存在if[!-e$WDOG_DEVICE];thenecho看门狗设备不存在:$WDOG_DEVICEexit1fi# 打开看门狗设备写入任意字符即喂狗# 注意一旦打开必须持续喂狗否则超时系统复位exec3$WDOG_DEVICEecho看门狗喂狗启动间隔:${FEED_INTERVAL}秒feed_count0whiletrue;do# 写入喂狗字符forretryin$(seq1$MAX_FEED_RETRIES);doifecho13;thenfeed_count$((feed_count1))breakelseecho喂狗失败重试$retry/$MAX_FEED_RETRIESsleep1fidone# 额外检查关键进程是否存活if!pgrep-xmain_app/dev/null;thenecho关键进程异常停止喂狗等待看门狗复位系统exec3-# 关闭看门狗停止喂狗触发超时复位exit1fisleep$FEED_INTERVALdone这段脚本有两个核心机制正常喂狗每10秒写一次/dev/watchdog告知硬件系统正常运行主动停喂检测到关键进程崩溃时主动关闭看门狗文件描述符不再喂狗让看门狗超时触发硬件复位这不是简单的定时写文件而是把进程健康检查和系统复位联动起来——软件自己发现问题时主动触发重启比等看门狗被动超时更快更可控。六、实战脚本4程序守护脚本工控程序崩溃是常态——内存泄漏、通信超时、硬件异常都可能导致进程退出。守护脚本的任务是检测到进程不在立即重启。#!/bin/bash# process_guard.sh - 程序守护脚本set-uAPP_NAMEdata_collectorAPP_CMD/opt/app/data_collector --config /etc/app/config.iniAPP_DIR/opt/appCHECK_INTERVAL5RESTART_DELAY3MAX_RESTART_COUNT10# 一小时内最多重启10次防止无限重启循环RESTART_WINDOW3600# 重启计数窗口1小时restart_count0window_start$(date%s)log_msg(){logger-tguard[$APP_NAME]$1}whiletrue;doifpgrep-x$APP_NAME/dev/null;then# 进程存活重置重启计数窗口restart_count0window_start$(date%s)sleep$CHECK_INTERVALcontinuefi# 进程不存在now$(date%s)elapsed$((now-window_start))# 重置窗口计数if[$elapsed-ge$RESTART_WINDOW];thenrestart_count0window_start$nowfi# 检查重启次数限制restart_count$((restart_count1))if[$restart_count-ge$MAX_RESTART_COUNT];thenlog_msg重启次数超限(${MAX_RESTART_COUNT}次/${RESTART_WINDOW}秒)停止守护# 可选触发看门狗或告警通知exit1filog_msg进程$APP_NAME不存在第${restart_count}次重启# 重启进程cd$APP_DIRnohup$APP_CMD/var/log/app/guard.log21sleep$RESTART_DELAYdone这个脚本有防无限重启机制1小时内重启超过10次就停止守护。连续崩溃说明问题不是偶发的继续重启只会反复日志刷屏不如停下来报警让运维介入。七、Shell脚本调试技巧7.1 bash -x 调试模式# 运行脚本时开启调试每行执行前都会打印bash-x/usr/local/bin/auto_mount.sh# 输出类似# MOUNT_POINT/mnt/usb# find_usb_device# for dev in /dev/sda1 /dev/sda2 /dev/sdb1# [ -b /dev/sda1 ]7.2 set选项组合#!/bin/bashset-e# 遇到错误立即退出set-u# 引用未定义变量时报错防止$VAR空值导致意外set-opipefail# 管道中任一命令失败整条管道返回失败工控脚本建议加上这三行让脚本在错误时立即停止而不是带着问题继续跑——继续跑往往比停下来后果更严重。八、crontab定时执行配置有些脚本不需要常驻运行定时执行即可# 编辑crontabcrontab-e# 每天凌晨2点执行日志归档02* * * /usr/local/bin/log_archive.sh# 每5分钟检查U盘挂载*/5 * * * * /usr/local/bin/auto_mount.sh# 每小时检查磁盘空间超过90%报警0* * * * /usr/local/bin/disk_check.sh# crontab时间格式分 时 日 月 周# * 表示任意值# */5 表示每5分钟# 0 2 * * * 表示每天2:00Shell脚本在工控里不是配角是基础设施。挂载、归档、喂狗、守护——四个脚本覆盖了工控设备最核心的运维自动化需求。写好这些脚本设备才能在无人现场稳稳运行。