使用getopt解析为负值的参数-使getopt忽略它们的任何方法吗?

问题描述

我正在使用getopt解析脚本的命令行参数。 所有可选参数(-o和--long)都由getopt处理,但也有强制性参数。参数4可以是路径或值的序列,这些值可以为负。

script.sh mandatory/path/one mandatory/path/two mandatory/file.txt -200.12,32.7,-18.7

如果参数4以负值开头,则-将触发getopt。显然,这会破坏脚本,因为getopt将抱怨未定义的选项。

我可以想到两种解决方法,但这两种方法都很hacky:

  1. 在$ @上执行sed操作,以用一些伪字符串替换-,然后在解析完成getopt之后再次进行sed操作,以再次用-替换伪对象。
ARGS=$(echo "$@" | sed -E "s/-([0-9])/%dummy%\1/g")
set -- "$ARGS"
ARGS=`getopt -o n -l no-act -n $0 -- "$@"`
eval set -- "$ARGS"
while :; do
  case "$1" in
    -n|--no-act)
      norun=1 ;;
    --) 
      shift; break ;;
    *)
      break 
  esac
  shift
done
ARGS=$(echo "$@" | sed -E "s/%dummy%([0-9])/-\1/g")
eval set -- "$ARGS"
  1. 使用getopt -1234567890中的参数定义选项。这会将强制参数4拆分为-200.12,-18.7,可以将其合并为中间变量。最后,必需的参数1-3和4必须再次为set
ARGS=`getopt -o n1:2:3:4:5:6:7:8:9:0: -l no-act -n $0 -- "$@"`
eval set -- "$ARGS"
while :; do
  case "$1" in
    -n|--no-act)
      norun=1 ;;
    -1|-2|-3|-4|-5|-6|-7|-8|-9|-0)
      TEMPVAR=$1$2
      shift ;;
    --) 
      shift; break ;;
    *)
      break 
  esac
  shift
done

必须有一种更优雅的方法来做到这一点。 Getopt在其他方面做得很好,我希望保留它用于命令行解析。

(还有更多选项,我在示例中仅提及-n选项以使代码块简短)

编辑:强制性参数4应该保持为$ 4,因为这行还有进一步的检查。

解决方法

有-种。这里的问题是,getopt命令除了以连字符开头的选项之外,实际上不了解其他任何内容,也不能说服它使用除连字符以外的其他内容作为选项的领导。无法告诉getopt不要以任何其他方式处理选项。

但是,getopt不处理参数。它只是将其传递到$OPTARG变量中,而没有任何解析。因此,这里有三个选项:

  1. 如果您的选择是固定的,则无需在此处使用getopt。只需照常使用$1$2$3,然后以错误的计数和/或格式错误的数字列表使脚本失败。您始终可以计算参数的数量,如果需要,可以将最后一个作为列表。
  2. 另一方面,如果您的选项不是 位置,那么您确实应该考虑为数字列表提供自己的选项,然后专门解释$OPTARG
  3. 如果您做的很特别,请创建自己的选项分析循环。 getopt是为完成相对简单的任务而设计的,诸如扩展其用途之类的东西。

以上任何内容通常都可以在有用的脚本中完成。我鼓励您不要使问题复杂化。脚本应该相对简单,并且Bash最好用作命令构造和调度语言。 Bash(也许只是sh?)是发行版中默认情况下唯一可用的语言,我们生活的时代已不复存在。如果您要进行一些相当复杂的参数处理,则应强烈考虑使用Perl,Python或Ruby之类的通用编程语言是否是您打算做的更好的选择。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...