1

所以我一直在阅读有关 getopts、getopt 等的信息,但我还没有找到解决问题的确切方法。

我的脚本使用的基本思想是:

./program [-u] [-s] [-d] <TEXT>

如果通过了 -d,则不需要 TEXT。请注意,TEXT 通常是一段文本。

我的主要问题是,一旦 getopts 完成对标志的解析,我就无法知道 TEXT 参数的位置。我可以假设 TEXT 是最后一个参数,但是,如果用户搞砸并执行以下操作:

./program -u "sentence 1" "sentence 2"

那么程序将不会意识到用法不正确。

我最接近的是使用 getopt 和 IFS 做

ARGS=$(getopt usd: $*)
IFS=' ' read -a array <<< "$ARGS"

唯一的问题是 TEXT 可能是一段很长的文本,并且由于空格,此方法会拆分文本的每个单词。

我认为我最好的选择是使用正则表达式来确保正确形成用法,然后使用 getopts 提取参数,但如果有更简单的解决方案会很好

4

2 回答 2

3

这很简单getopts

#!/bin/bash
u_set=0
s_set=0
d_set=0
while getopts usd OPT; do
  case "$OPT" in
    u) u_set=1;;
    s) s_set=1;;
    d) d_set=1;;
    *) # getopts produces error
       exit 1;;
  esac
done
if ((!d_set && OPTIND>$#)); then
  echo You must provide text or use -d >>/dev/stderr
  exit 1
fi
# The easiest way to get rid of the processed options:
shift $((OPTIND-1))
# This will run all of the remaining arguments together with spaces between them:
TEXT="$*"
于 2013-10-02T23:06:20.047 回答
0

这是我通常做的:

local badflag=""
local aflag=""
local bflag=""
local cflag=""
local dflag=""

while [[ "$1" == -* ]]; do
  case $1 in
    -a)
      aflag="-a"
      ;;

    -b)
      bflag="-b"
      ;;

    -c)
      cflag="-c"
      ;;

    -d)
      dflag="-d"
      ;;

    *)
      badflag=$1
      ;;
  esac
  shift
done

if [ "$badflag" != "" ]; do
    echo "ERROR CONDITION"
fi

if [ "$1" == "" ] && [ "$dflag" == "" ]; do
    echo "ERROR CONDITION"
fi

local remaining_text=$@
于 2013-10-02T21:34:34.930 回答