如何在Bash脚本中验证Crontab调度参数的合法性
扩展Bash脚本的Crontab参数验证逻辑
核心思路
要支持Crontab的完整语法(范围-、列表,、步长/),需分层次验证:先匹配整体格式合法性,再拆分每个子部分验证数值是否符合对应字段的范围要求,确保所有格式场景都能覆盖。
步骤1:更新使用说明
先修改print_usage函数,明确标注支持的所有参数格式:
function print_usage() { echo "Usage: `basename $0` -a APPLICATION [-D DAY_OF_WEEK] [-M MONTH] [-d DAY_OF_MONTH] [-H HOUR] [-m MINUTE] [-u]" echo "Options:" echo " -a APPLICATION EMR application (application:container)" echo " -D DAY_OF_WEEK 星期几 (0 - 7,周日=0或7),支持格式:*、单个数字、范围(如1-5)、列表(如0,6,7)、步长(如*/2或1-5/2)" echo " -M MONTH 月份 (1 - 12),支持格式:*、单个数字、范围(如1-6)、列表(如1,3,5)、步长(如*/3或1-6/2)" echo " -d DAY_OF_MONTH 日期 (1 - 31),支持格式:*、单个数字、范围(如1-15)、列表(如1,15,30)、步长(如*/5或1-15/3)" echo " -H HOUR 小时 (0 - 23),支持格式:*、单个数字、范围(如9-18)、列表(如9,12,18)、步长(如*/4或9-18/3)" echo " -m MINUTE 分钟 (0 - 59),支持格式:*、单个数字、范围(如0-45)、列表(如0,15,30)、步长(如*/15或0-45/15)" echo " -u 卸载该应用的CRON任务" exit 0 }
步骤2:编写通用验证函数
为避免重复代码,编写一个通用函数,接收待验证字段值、该字段的最小/最大值,统一处理所有格式的验证:
# 验证Crontab字段格式合法性 # 参数1:待验证的字段值 # 参数2:字段允许的最小值 # 参数3:字段允许的最大值 validate_cron_field() { local field="$1" local min="$2" local max="$3" # 先匹配整体格式:* / 数字/数字 / 范围/数字 / 逗号分隔的上述格式组合 if [[ ! "$field" =~ ^(\*|([0-9]+(-[0-9]+)?)(/[0-9]+)?)(,([0-9]+(-[0-9]+)?)(/[0-9]+)?)*$ ]]; then return 1 fi # 拆分每个子部分逐一验证 IFS=',' read -ra parts <<< "$field" for part in "${parts[@]}"; do # 处理带步长的情况 if [[ "$part" =~ ^([\*-]?[0-9]+(-[0-9]+)?)/([0-9]+)$ ]]; then local base="${BASH_REMATCH[1]}" local step="${BASH_REMATCH[3]}" # 步长必须是正整数 if ! [[ "$step" =~ ^[1-9][0-9]*$ ]]; then return 1 fi # 验证基准部分(* / 范围 / 单个数字) if [[ "$base" == "*" ]]; then continue elif [[ "$base" =~ ^([0-9]+)-([0-9]+)$ ]]; then local start="${BASH_REMATCH[1]}" local end="${BASH_REMATCH[2]}" if (( start < min || end > max || start > end )); then return 1 fi else if (( base < min || base > max )); then return 1 fi fi elif [[ "$part" =~ ^([0-9]+)-([0-9]+)$ ]]; then # 处理范围格式 local start="${BASH_REMATCH[1]}" local end="${BASH_REMATCH[2]}" if (( start < min || end > max || start > end )); then return 1 fi elif [[ "$part" == "*" ]]; then continue else # 处理单个数字格式 if (( part < min || part > max )); then return 1 fi fi done return 0 }
步骤3:替换原有验证逻辑
用通用函数替换之前的单字段验证代码,简化逻辑:
# 验证星期几参数 if ! validate_cron_field "$DAY_OF_WEEK" 0 7; then echo "ERROR: DAY_OF_WEEK 参数格式无效,需符合Crontab语法,合法范围0-7(周日=0或7)" exit 1 fi # 验证月份参数 if ! validate_cron_field "$MONTH" 1 12; then echo "ERROR: MONTH 参数格式无效,需符合Crontab语法,合法范围1-12" exit 1 fi # 验证日期参数 if ! validate_cron_field "$DAY_OF_MONTH" 1 31; then echo "ERROR: DAY_OF_MONTH 参数格式无效,需符合Crontab语法,合法范围1-31" exit 1 fi # 验证小时参数 if ! validate_cron_field "$HOUR" 0 23; then echo "ERROR: HOUR 参数格式无效,需符合Crontab语法,合法范围0-23" exit 1 fi # 验证分钟参数 if ! validate_cron_field "$MINUTE" 0 59; then echo "ERROR: MINUTE 参数格式无效,需符合Crontab语法,合法范围0-59" exit 1 fi
关键说明
- 通用函数先通过正则匹配整体格式,确保输入属于Crontab合法格式集合
- 拆分每个子部分后,分别验证范围的起止顺序、数值区间、步长合法性
- 支持
*/15(每15分钟)、1-5(周一到周五)、0,6,7(周六日)、1-5/2(周一、周三、周五)等所有常用Crontab格式
内容的提问来源于stack exchange,提问作者dokgu
相关产品推荐
相关产品推荐

