传参的格式
用 -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.