linux GNU getopt:忽略未知的可选参数?

时间:2014-07-11 20:02:22

标签: linux bash getopt

是否可以使用GNU getopt忽略未知的可选参数?

我有一个脚本scriptA.sh,它有可选参数--optA, --optB, --optC, --optD

我想编写一个包装器,wrapperA,带有两个可选参数--optX and --optY,调用scriptA。但是,我不想在包装器中声明scriptA的所有可选参数。

特别是,如果在wrapperA内,我用

指定可选参数
getopt --longoptions optX:,optY:

电话

wrapperA --optX --optA --optB

返回错误

getopt: unknown option -- optA

GNU getopt是否可以强制忽略未知参数并将它们放在' - '之后。在其输出?

4 个答案:

答案 0 :(得分:6)

无法告诉GNU getopt忽略未知选项。如果你真的想要这个功能,你必须编写自己的选项解析器。

只是忽略未知选项并不简单。你怎么知道一个未知的选项是否会引用一个参数?

原始脚本的示例用法:

originalscript --mode foo source

此处foo是选项--mode的参数。而source是"非选项参数" (有时称为"位置参数")。

包装器脚本的示例用法:

wrapperscript --with template --mode foo source

wrapperscript中的getopt如何知道它应该与--mode一起忽略foo?如果它只是忽略--mode,则originalscript会将foo作为第一个位置参数。

一种可能的解决方法是告诉包装器脚本的用户在双短划线(--)之后写入原始脚本的所有选项。按照惯例,双破折号标志着选项的结束。 GNU getopt识别双破折号并停止解析并将其余部分作为位置参数返回。

另见:

答案 1 :(得分:3)

我正在研究类似的事情,并发现这可以阻止getopt错误来解决这些错误。基本上只是将错误传递给遗忘。

while getopts "i:s:" opt > /dev/null 2>&1; do
    case $opt in
      i)
        END=$OPTARG
      ;;
    esac
done
./innerscript $*

$ ./blah.sh -s 20140503 -i 3 -a -b -c

答案 2 :(得分:0)

如果只想忽略stderr,可以按如下所示将2>dev/null附加到while的起始行。我认为您也可以将其用于getopt

while getopts "a:p:" opt 2>/dev/null
do
    case $opt in
      \?)
        echo "any error comment you want" 1>&2
        exit 1
        ;;
    esac
done

答案 3 :(得分:0)

好吧,我可以解决这个问题。这个想法涉及在遇到未知选项时摆弄OPTIND,以便getopts可以继续进行解析。因此,我们需要保持解析的位置,以便可以相应地调整OPTIND

local parse_index=1 # initialize to cater for the first option coming out unknown
while getopts ':m:t:r:u:p:' opt; do
  case $opt in
    m) build_module="$OPTARG"
       parse_index=$OPTIND
       ;;
    t) build_tag="$OPTARG"
       parse_index=$OPTIND
       ;;
    r) container_registry="$OPTARG"
       parse_index=$OPTIND
       ;;
    u) registry_username="$OPTARG"
       parse_index=$OPTIND
       ;;
    p) registry_password="$OPTARG"
       parse_index=$OPTIND
       ;;
    :) echo "Option -$OPTARG requires an argument" >/dev/stderr
       ;;
   \?) echo "Unknown option: -$OPTARG"
       ((OPTIND = $parse_index + 2))    # fool `getopts` to continue parsing
       parse_index=$OPTIND      # adjust to cater for successive unknown options
       ;;
  esac
done

我使用了一个假设,即遇到未知选项时会带有一个参数,因此((OPTIND = $parse_index + 2))部分适合您的情况。该假设证明是脆弱的且非包容性的,但是在这种情况下有效。还要注意,如果出现错误(缺少参数),它仍然会中断。

显然,这不是一种通用且清洁的方法,但是它有助于克服没有其他选择的情况。