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 将被设置为已查找到的选项字符,并且 标准错误中将不写入任何输出。

示例:

bash 复制代码
#!/bin/bash

#java21 -jar mcp-server-mysql-webmvc-0.0.1-SNAPSHOT.jar --datasource.config=./datasource.yml


file="mcp-server-mysql-webmvc-0.0.1-SNAPSHOT.jar"
# pnamekey used by getPid for find process by name, eg: mcp-server-mysql-webmvc
pnamekey=$(echo $file | sed -E s/-[0-9\.]+.*//g)
java_opt_default="--datasource.config=./datasource.yml"
java_opt=""
pid=
args=""


# init 
h_idx=-1
d_idx=-1
o_idx=-1
o_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
      ;;
  esac
done


if [ $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"
fi

if [ $o_idx -eq -1 ]; then
  java_opt=$java_opt_default
else
  java_opt=$o_val
fi


function getPid() {
  local name=$1
  pid=$(ps aux |grep $name |grep -v "grep" | awk '{print $2}')
}

# check already is running
getPid $pnamekey
if [ -n "$pid" ]; then
  echo -e "\n$pnamekey already is running, pid = $pid \n"
  exit
fi


echo -e "\njava21 $args -jar $file 2>&1 &"
#nohup java21 $args -cp $file $class 2>&1 &
java21 $args -jar $file 2>&1 &


# check run success/failed
getPid $pnamekey
if [ -z "$pid" ]; then
  echo -e "$pnamekey start failed!\n"
  exit
else
  echo -e "$pnamekey start success! pid = $pid\n"
fi
相关推荐
A小辣椒9 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒12 小时前
TShark:基础知识
linux
AlfredZhao15 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao1 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334661 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式