将 getopts 选项自动解析为 bash 中同名的动态变量

Automatic parsing of getopts options into dynamic variables of same name in bash

我有一个 bash 脚本,我写了 3 个命令行选项,bib、bob 和 boo...我想将用户选项读入 bash 变量相同的名字,我这样做如下:

PARSED_OPTIONS=$(getopt -n [=11=]  --long "bib:,bob:,boo:"  -- "$@")

eval set -- "$PARSED_OPTIONS";

while true; do
  case "" in

  --bib)
  bib=
  shift 2;;

  --bob)
  bob=
  shift 2;;

  --boo)
  boo=
  shift 2 ;;

  --)
  shift
  break;;

  esac
done

这一切都很好,到目前为止,一切顺利...

但现在我想将它扩展到一个包含许多选项的列表,所以与其写出一个长长的 case 语句,不如能够以某种方式遍历选项列表并自动通过变量的选项,沿着这些线

opts="bib:,bob:,boo:," 

PARSED_OPTIONS=$(getopt -n [=12=]  --long $opts -- "$@")

for arg in `echo $opts | tr , " "` ; do 
  eval set -- "$PARSED_OPTIONS";
  while true; do

    case "" in
      --${arg})
      declare $arg=
      shift 2
      ;;
      --)
      shift
      break;;
    esac
  done
done

我正在使用声明语句将参数放入同名的动态变量中(参见 Dynamic variable names in Bash second solution), and this solution to do the loop over comma separated lists Loop through a comma-separated shell variable 但我在这里得到一个无限循环。我认为是因为允许使用 2 个未使用的选项因为它们在 PARSED_OPTIONS 列表中,但是它们不会在循环中被切掉,因为只查找 "arg" ......我看不到一个明显的解决方法,但我是当然有。

我意识到 case 语句中仍然有 shift 命令,这就是它没有退出的原因。我还需要从参数中去掉冒号 : ,所以这是我对一个有效的 bash 脚本的自动参数检索:

# specify an arbitrary list of arguments:

opts=bib:,bob:,boo:

PARSED_OPTIONS=$(getopt -n [=10=]  --long "${opts}"  -- "$@")

for arg in ${opts//,/ } ; do 
  var=${arg//:} # remove the colon
  eval set -- "$PARSED_OPTIONS";
  while true ; do
    case "" in
      --${var})
      declare ${var}=
      ;;
    --)
      break
      ;;
    esac
    shift 2
  done
done

所以如果你尝试 test_script --boo 3 --bib hello --bob lkkfrfrfr

echo $bib $bob $boo

应该给

hello lkkfrfrfr 3