Linux shell getopts 解析命令行参数
Linux shell getopts 解析命令行参数
getopts
语法
getopts 选项字符串 名称 [ 参数 ...]
示例1(有前置冒号):
while getopts \":hdo:\" optname;
do
......
done
示例1(无前置冒号)
while getopts \"hdo:\" optname;
do
......
done
说明:
optstring 选项字符串,即 option 字符串,会逐个匹配
varname 变量名称,保存每次匹配成功的选项
arg 参数列表,没写时它会取命令行参数列表
$OPTIND 特殊变量/全局变量,option index,会逐个递增
$OPTARG 特殊变量/全局变量,option argument,不同情况下有不同的值
注意:
1)当 optstring 以 : 开头时(有前置冒号),getopts 会区分 illegal option 错误(非法选项)和 option requires an argument 错误(选项缺少参数)。
illegal option(非法选项)时,varname 会被设成 ?(问号) ,$OPTARG 保存出问题的 option;
option requires an argument(选项缺少参数) 时,varname会被设成 :(冒号) ,$OPTARG 保存出问题的 option;
2)当 optstring 无 : 开头时(无前置冒号),illegal option 错误(非法选项)和 option requires an argument 错误(选项缺少参数)都会使 varname 被设成 ?(问号),$OPTARG 保存出问题的 option;
3)当 optstring 中的字符后面跟 ”:“ 时(有后置冒号),表明该 option 要接收参数,参数(argument)保存在 $OPTARG 中;
如果缺参数,且 optstring 是以”:“开头(有前置冒号),则 varname 的值会被设置成 :(冒号),$OPTARG 保存了该 option;
否则 varname 的值是 ?(问号),$OPTARG 保存了该 option。
每次调用 getopts 命令时,它将下一个选项的值放置在名称内,并将下一个要处理的参数的索引置于 shell 变量 OPTIND 中。一旦调用了shell , OPTIND 将初始化为 1。
如果选项字符串中的字符后面带有 : (有后置冒号),则预期此选项将带有参数。当选项需要选项参数时,getopts 命令就将其置于变量 OPTARG 中。
当查找到选项字符串所不包含的选项字符(即不支持的选项),或者查找到的选项没有所需的选项参数时(即虽然选项支持,但选项需要参数,参数却没有传入):
1)如果选项字符串不以前置 :(前置冒号)开头,名称 将会被设置为 ?(问号)字符,OPTARG 将被取消设置,并且诊断消息将被写入到标准错误中。
2)如果选项字符串以前置 :(前置冒号)开头,名称 将被设为 ?(问号)字符,这是对不支持的选项来说的,或者为缺少参数的所需选项设为:(冒号)字符,OPTARG 将被设置为已查找到的选项字符,并且 标准错误中将不写入任何输出。
示例:
#!/bin/bash#java21 -jar mcp-server-mysql-webmvc-0.0.1-SNAPSHOT.jar --datasource.config=./datasource.ymlfile=\"mcp-server-mysql-webmvc-0.0.1-SNAPSHOT.jar\"# pnamekey used by getPid for find process by name, eg: mcp-server-mysql-webmvcpnamekey=$(echo $file | sed -E s/-[0-9\\.]+.*//g)java_opt_default=\"--datasource.config=./datasource.yml\"java_opt=\"\"pid=args=\"\"# init h_idx=-1d_idx=-1o_idx=-1o_val=\"\"function showHelp() { echo -e \"\\n***********************************************************************\\n\" echo -e \"Use $0 [ -h | [ -d ] [ -o java_run_option ] ] \\n\" echo -e \" -h: show help\" echo -e \" -d: enable debug server, default port is 5005\" echo -e \" -o: special java run option, if not special -o, default behavior is: -o $java_opt_default\" echo -e \"\\n eg: \" echo -e \" $0 -h # show help\" echo -e \" $0 # run without args\" echo -e \" $0 -o $java_opt_default # run with special java run option\" echo -e \" $0 -d # run with enable debug server\" echo -e \" $0 -d -o $java_opt_default # run with enable debug server and special java run option\" echo -e \"\\n***********************************************************************\\n\"}while getopts \":hdo:\" optname;do case \"$optname\" in h) h_idx=$OPTIND showHelp exit 0 ;; d) d_idx=$OPTIND ;; o) o_idx=$OPTIND o_val=$OPTARG ;; :) echo \"Option[$(expr $OPTIND - 1)] -$OPTARG required an argument\" exit 1 ;; ?) echo \"Invalid option[$(expr $OPTIND - 1)]: -$OPTARG\" exit 1 ;; *) # should not occur echo \"Invalid option[$(expr $OPTIND - 1)]: -$OPTARG\" exit 1 ;; esacdoneif [ $d_idx -ne -1 ]; then # enable debug if input args inluce \"-d\" option echo \"enable debug server\" args=\"$args -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:5005\"fiif [ $o_idx -eq -1 ]; then java_opt=$java_opt_defaultelse java_opt=$o_valfifunction getPid() { local name=$1 pid=$(ps aux |grep $name |grep -v \"grep\" | awk \'{print $2}\')}# check already is runninggetPid $pnamekeyif [ -n \"$pid\" ]; then echo -e \"\\n$pnamekey already is running, pid = $pid \\n\" exitfiecho -e \"\\njava21 $args -jar $file 2>&1 &\"#nohup java21 $args -cp $file $class 2>&1 &java21 $args -jar $file 2>&1 &# check run success/failedgetPid $pnamekeyif [ -z \"$pid\" ]; then echo -e \"$pnamekey start failed!\\n\" exitelse echo -e \"$pnamekey start success! pid = $pid\\n\"fi