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
相关推荐
茶本无香1 小时前
Java调用Shell脚本执行SQL数据库操作:从入门到实战
java·sql·shell
HiDev_1 小时前
【非标自动化】2、认识元器件(固态继电器)
运维·自动化
明达智控技术1 小时前
国产 PLC 落地立库自动化,MC5000边缘智能控制器破局
运维·自动化
小绫网络安全2 小时前
Kali Linux渗透测试入门教程:从零搭建到实战攻防
linux·运维·服务器
西安景驰电子2 小时前
《PTP精确时间协议系列》第一篇:从原理到应用,全面解读IEEE 1588
linux·运维·服务器·开发语言·网络·windows·php
猫吃了源码3 小时前
k9s简介和安装
linux·docker·kubernetes
云原生指北4 小时前
Docker Sandboxes 上手:从安装到第一次跑 Agent
运维·docker·容器
小马同学-4 小时前
高可用-Keepalived全解析
linux·运维
ziyun6668884 小时前
Docker 容器化 Web 服务架构搭建与自动化运维项目
运维·docker·架构
Forever Nore5 小时前
LeetCode 13 罗马数字转整数 - 按规则处理
linux·服务器·leetcode