定时任务

定时任务
    指定某个日志或时间周期性的执行命令
        ps -ef |grep crond 
    使用场景
    1.数据备份
    2.服务器巡检
        #!/bin/bash

        # 正确写法:使用 $() 包裹命令,外层用双引号
        mem_total=$(free -m | awk 'NR==2 {print $2}')
        mem_used=$(free -m | awk 'NR==2 {print $3}')
        mem_free=$(free -m | awk 'NR==2 {print $4}')
        mem_rate=$(free -m | awk 'NR==2 {printf "%.2f%%\n", ($3/$2)*100}')

        echo '----mem check info ----'
        echo "总内存: ${mem_total}MB"
        echo "已使用: ${mem_used}MB"
        echo "还剩余: ${mem_free}MB"
        echo "使用率: ${mem_rate}"
    3.日志切割
        cp /var/log/messages /var/log/messages-$(date +%Y%m%d -d '-1 day')
    4.临时文件清理
    5.时间同步
    定时任务管理
        确认命令所在目录
        which 命令
        which cat
            /usr/bin/cat 所在目录

        定时任务配置
        cat /etc/crontab
            SHELL=/bin/bash
            PATH=/sbin:/bin:/usr/sbin:/usr/bin
            MAILTO=root

            # For details see man 4 crontabs

            # Example of job definition:
            # .---------------- minute (0 - 59)
            # |  .------------- hour (0 - 23)
            # |  |  .---------- day of month (1 - 31)
            # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
            # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
            # |  |  |  |  |
            # *  *  *  *  * user-name  command to be executed
            * * * * * root echo "hello world"
            #*表示任意(分时日月周)都会执行
            #2-3表示一个时间范围
            #,表示分隔2,4,6
            #/2每隔多久
        crontab 
            -e‌ 编辑当前用户(或指定用户)的crontab文件
            -l 列出当前用户(或指定用户)的crontab文件内容
            -r 删除当前用户(或指定用户)的整个crontab文件
            -u 指定操作用户(通常需要root权限)
    备份案例
        主机名    内网IP
        Lt        192.168.30.90

        需求
            1.提前准备备份文件的目录,目录规则:/backup/当前主机名_当前主机ip_当前时间
            2.打包备份文件,名字2018-02-20_hostname_etc.tar.gz
            3.验证文件是否完整
            4.将验证结果发送到邮箱
            5.存放备份内容的目录要求只保留3天的数据
            6.每天凌晨3:50执行该备份
            
        脚本统一放在/scripts
        增加r+x权限
        执行脚本后,复制该执行命令,以便写入cron
        
        编写脚本
            #!/bin/bash
            # ==================== 配置 ====================
            BACKUP_BASE="/backup"
            DATE=$(date +%Y-%m-%d)
            TIME=$(date +%H%M%S)
            DATETIME=$(date +%Y-%m-%d_%H%M%S)
            HOSTNAME=$(hostname)
            IP=$(hostname -I | awk '{print $1}')  # 获取主IP

            # 邮件配置
            MAIL_TO="admin@yourcompany.com"
            MAIL_SUBJECT="备份报告 - ${HOSTNAME} - ${DATE}"

            # 备份目录规则:/backup/主机名_主机IP_当前时间
            BACKUP_DIR="${BACKUP_BASE}/${HOSTNAME}_${IP}_${DATETIME}"
            BACKUP_FILE="${DATE}_${HOSTNAME}_etc.tar.gz"
            BACKUP_PATH="${BACKUP_DIR}/${BACKUP_FILE}"

            # 日志文件
            LOG_FILE="${BACKUP_DIR}/backup.log"

            # ==================== 1. 创建备份目录 ====================
            mkdir -p "$BACKUP_DIR" || {
                echo "错误:无法创建备份目录 $BACKUP_DIR" | mail -s "备份失败 - ${HOSTNAME}" "$MAIL_TO"
                exit 1
            }

            # 开始记录日志
            {
            echo "========================================"
            echo "备份开始时间: $(date '+%Y-%m-%d %H:%M:%S')"
            echo "主机名: $HOSTNAME"
            echo "IP地址: $IP"
            echo "备份目录: $BACKUP_DIR"
            echo "备份文件: $BACKUP_FILE"
            echo "========================================"

            # ==================== 2. 打包备份文件 ====================
            echo "[$(date '+%H:%M:%S')] 开始打包 /etc 目录..."
            if tar -czf "$BACKUP_PATH" /etc 2>/dev/null; then
                echo "[$(date '+%H:%M:%S')] 打包完成: $BACKUP_PATH"
                FILE_SIZE=$(du -h "$BACKUP_PATH" | cut -f1)
                echo "[$(date '+%H:%M:%S')] 文件大小: $FILE_SIZE"
            else
                echo "[$(date '+%H:%M:%S')] 错误:打包失败"
                echo "备份失败:无法创建 tar.gz 文件" | mail -s "备份失败 - ${HOSTNAME}" "$MAIL_TO"
                exit 1
            fi

            # ==================== 3. 验证文件完整性 ====================
            echo "[$(date '+%H:%M:%S')] 开始验证文件完整性..."

            # 检查文件是否存在且非空
            if [ ! -s "$BACKUP_PATH" ]; then
                echo "[$(date '+%H:%M:%S')] 错误:备份文件不存在或为空"
                VERIFY_STATUS="失败:文件不存在或为空"
                VERIFY_RESULT="FAILED"
            else
                # 测试 tar.gz 完整性
                if tar -tzf "$BACKUP_PATH" >/dev/null 2>&1; then
                    echo "[$(date '+%H:%M:%S')] 验证通过:tar.gz 文件完整"
                    VERIFY_STATUS="成功:文件完整,测试解压正常"
                    VERIFY_RESULT="SUCCESS"
                    
                    # 额外检查:统计文件数
                    FILE_COUNT=$(tar -tzf "$BACKUP_PATH" | wc -l)
                    echo "[$(date '+%H:%M:%S')] 备份文件数: $FILE_COUNT"
                else
                    echo "[$(date '+%H:%M:%S')] 错误:tar.gz 文件损坏或无效"
                    VERIFY_STATUS="失败:文件损坏或无法解压"
                    VERIFY_RESULT="FAILED"
                fi
            fi

            # 计算 MD5 校验值
            if [ "$VERIFY_RESULT" = "SUCCESS" ]; then
                MD5=$(md5sum "$BACKUP_PATH" | awk '{print $1}')
                echo "[$(date '+%H:%M:%S')] MD5: $MD5"
                echo "$MD5  $BACKUP_FILE" > "${BACKUP_PATH}.md5"
            else
                MD5="N/A"
            fi

            echo "[$(date '+%H:%M:%S')] 验证结果: $VERIFY_STATUS"

            # ==================== 4. 发送邮件报告 ====================
            echo "[$(date '+%H:%M:%S')] 发送邮件报告..."

            MAIL_BODY="备份报告 - ${HOSTNAME}
            ========================================
            备份时间: $(date '+%Y-%m-%d %H:%M:%S')
            主机名: ${HOSTNAME}
            IP地址: ${IP}
            备份目录: ${BACKUP_DIR}

            文件信息:
              文件名: ${BACKUP_FILE}
              大小: ${FILE_SIZE:-N/A}
              文件数: ${FILE_COUNT:-N/A}
              MD5: ${MD5}

            验证结果: ${VERIFY_STATUS}

            ========================================
            此邮件由自动备份系统发送
            "

            if echo "$MAIL_BODY" | mail -s "$MAIL_SUBJECT [$VERIFY_RESULT]" "$MAIL_TO"; then
                echo "[$(date '+%H:%M:%S')] 邮件发送成功"
            else
                echo "[$(date '+%H:%M:%S')] 警告:邮件发送失败"
            fi

            # ==================== 5. 清理3天前的备份 ====================
            echo "[$(date '+%H:%M:%S')] 清理3天前的备份数据..."

            # 查找并删除3天前的备份目录(按目录名中的时间或修改时间)
            DELETED_COUNT=0
            while IFS= read -r -d '' old_dir; do
                echo "[$(date '+%H:%M:%S')] 删除旧备份: $old_dir"
                rm -rf "$old_dir"
                ((DELETED_COUNT++))
            done < <(find "$BACKUP_BASE" -maxdepth 1 -type d -name "*_*_*" -mtime +3 -print0 2>/dev/null)

            echo "[$(date '+%H:%M:%S')] 清理完成,删除 $DELETED_COUNT 个旧备份目录"

            # ==================== 结束 ====================
            echo "[$(date '+%H:%M:%S')] 备份任务结束"
            echo "========================================"

            } >> "$LOG_FILE" 2>&1

            # 如果验证失败,返回非零退出码
            [ "$VERIFY_RESULT" = "SUCCESS" ] || exit 1
posted @ 2026-02-28 18:01  Dog17  阅读(4)  评论(0)    收藏  举报