传参的格式

用 -age=23 或 -age 23 这样用单横杠开头,等号或者空格隔开值
举例:sh xxxxx.sh -age 23 -name=qufudcj

脚本中引用传参

变量名就是参数名
比如: -age=23 用 ${age} 或 $age 都可以得到23

将下面的脚本内容添加在脚本头部,并酌情修改

需要修改的变量

  • 定义可以有哪些参数: list_args_conf 在17行
  • 定义必须有哪些参数: list_args_must 在19行
  • 定义某些参数的限定值,各值空格隔开,变量名需遵循格式:list_value_<你的传参名>,比如:list_value_age,在38行

你也可以尝试将这些内容写成shell函数放在单独文件里,然后在你的主脚本中引用
help功能还没完善,待更新

以下是脚本正文

# ------------------------------------------------------------------------------------
#                               以下内容是在定义传入参数的格式和限制
# ------------------------------------------------------------------------------------
# 作者:青梅煮茶
# 最后更新: 2021/10/11
# 为了兼容新老shell版本,没有使用字典
# 定义传参,格式:  -age=23 或 -age 23
# 引用传参的格式为: 比如 -age=23 用 ${age} 或 $age 都可以
# -action 动作类型,只能为:stop start restart check
# -isrm 是否删除已存在的exec文件,all是所有,input是info中的程序名才删除,no是不删除
# -ts 循环的间隔时间
# -info 程序的程序名和nodeport端口,分隔符必须正确,如:maycur-web-pro@@@30348###maycur-cluster-api@@@none


# 参数指定格式  -age=23 或 -age 23
# 定义可以有哪些参数
list_args_conf="action isrm ts info"
# 定义必须有哪些参数
list_args_must="action info ts isrm"
# 定义某些参数的值限制,看自己的需求增删,要随这些变量写相应的功能
list_value_action="stop start restart check"
list_value_isrm="all input no"

# 读取传入的参数并切割分组
# 旧版本正则,有值中不能带-的缺陷 list_args_input=`echo $@ | grep -o -e "\-[^ =]\{1,\}\( \{1,\}\|=\|$\)[^ -]\{0,\}"`
# 识别所有参数,并把每个参数和它的值归为一行
list_args_input=`echo $@ | grep -o -e "\(^-\| -\|-\)[^ =]\{1,\}\( \{1,\}\|=\|$\)\([^ -][^ ]\{0,\}\|[^ -]\{0,\}\)"`
# 临时修改for循环分隔符为换行符,因为传入的参数有可能不是 -open=yes 而是 -open yes 或干脆 -open 后没有跟任何值
IFS=$'\n'
for arg_conf in `echo "${list_args_input}"`;do
    # 判断是不是位置参数,是的话跳过(通过参数前有没有横杠来判断的,虽然上面的正则是不会匹配到的,但还是以防万一)
    n_arg_pos=`echo ${arg_conf} | grep -e "^\-" -e "^ \-" | wc -l`
    if [ ${n_arg_pos} -eq 0 ];then
        continue
    fi

    # 提取参数名
    arg_k=`echo ${arg_conf} | sed 's/^-\|^ -//g'| awk -F '[ =]' '{print $1}'`

    # 看看是不是需要的参数,不是的话报错退出,这里的list_args_conf是在脚本开头定义的
    # 不需要这个判断可以整体注释,不影响后面的功能
    n_arg_opt=`echo "${list_args_conf}" | grep -w ${arg_k} | wc -l`
    if [ "$n_arg_opt" -eq 0 ];then
        echo "[ERROR] 无效的参数:${arg_k}"
        exit 1
    fi

    # 给对应的变量赋值
    # 这里是先提取出传参的值:awk去掉第一段(参数名),不直接取第二段是为了防止参数值中有等号
    arg_v=`echo ${arg_conf} | sed 's/^-\|^ -//g'| awk -F '[ =]' '{gsub($(1),"");print}' | sed 's/^=\|^ \{1,\}//g'`
    # 通过eval先转译再执行的特性,使变量值可以作为变量名
    # 这里使用了export,方便后面的进程使用env判断这个参数有没有被传入
    eval export ${arg_k}="$arg_v"
    # 如果参数值为空,则报错
    # 若允许为空,可以注释这个判断,可通过env输出看看空变量有没有被传入过
    if [ -z "${arg_v}" ];then
        echo -e "[ERROR] ${arg_k}的值为空,请检查传入的数据或定义参数的格式,应该为:\n\t -${arg_k}=XXXX  或  -${arg_k} XXXX"
        exit 3
    fi
done

# 恢复for循环分隔符
IFS=$' '

# 看看必选参数是不是都有了,定义在开头的list_args_must变量中
# 不需要这个判断可以整体注释,不影响后面的功能,也可以将list_args_must变量置空
for arg_must in ${list_args_must};do
    n_arg_must=`echo "${@}" | grep -w "\-${arg_must}" | wc -l`
    if [ ${n_arg_must} -eq 0 ];then
        echo "[ERROR] 必选参数${arg_must}未指定,格式: -${arg_must}=XXXXXXXX"
        exit 2
    fi
done


# 传参值是否符合限制
# 以参数名为key_name循环
for key_name in ${list_args_conf};do
	# key_conf的值是限制值列表的变量名,根据参数名动态定义,这要求脚本顶部定义的变量名格式必须是: list_value_变量名
    key_conf="list_value_${key_name}"
    # value_conf的值是key_conf的值为变量名的值,也就是说里面是当前传参的限制值列表,使用了eval转译
    value_conf=`eval echo \\$${key_conf}`
    # value_input的值是当前传参的值,使用了eval转译获得
    value_input=`eval echo \\$${key_name}`
    # n_v_conf是数字类型值,当它为0时表示当前参数的值不在限定值列表list_value_XXXX中
    n_v_conf=`echo "${value_conf}" | grep -w "${value_input}" | wc -l`
    # n_v_env值是数字类型,当它不为0时表示这个参数在上面被定义过,在脚本执行的时候传递了这个参数
    n_v_env=`env | grep "^${key_name}=" | wc -l`
    # echo "[DEBUG] 参数${key_name}输入值为\"${value_input}\",设定的限制${key_conf}为[${value_conf}]"
    # 当在限定值列表不为空且其中找不到它,而它又已经被定义过了,那么报错退出
    if [ ${n_v_conf} -eq 0 -a ${n_v_env} -ne 0 -a -n "${value_conf}" ];then
        echo "[ERROR] 参数${key_name}的输入值\"${value_input}\"不正确,只支持: [${value_conf}]"
        exit 5
    fi
done

# ------------------------------------------------------------------------------------
#                               以上内容是在定义传入参数的格式和限制
# ------------------------------------------------------------------------------------

Q.E.D.


静坐常思己过,闲谈莫论人非