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

ulydmbyx  于 2023-06-21  发布在  Linux
关注(0)|答案(5)|浏览(141)

是否可以使用GNU getopt忽略未知的可选参数?
我有一个脚本scriptA.sh,它有可选参数--optA, --optB, --optC, --optD
我想写一个 Package 器wrapperA,它有两个可选参数--optX and --optY,用于调用scriptA。但是,我不想在 Package 器中声明scriptA的所有可选参数。
特别地,如果在wrapperA中,我用

getopt --longoptions optX:,optY:

电话

wrapperA --optX --optA --optB

返回错误

getopt: unknown option -- optA

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

gmxoilav

gmxoilav1#

不可能告诉GNU getopt忽略未知选项。如果你真的想要这个特性,你必须编写自己的选项解析器。
这并不像忽略未知选项那么简单。如何判断一个未知的选项是否接受参数?
原始脚本的使用示例:

originalscript --mode foo source

这里foo是选项--mode的参数。而source是“非选项参数”(有时称为“位置参数”)。
Package 器脚本的示例用法:

wrapperscript --with template --mode foo source

wrapperscript中的getopt如何知道它应该忽略--modefoo?如果它只是忽略--mode,那么originalscript将获得foo作为第一个位置参数。
一个可行的解决方法是告诉 Package 器脚本的用户在双破折号(--)之后写入原始脚本的所有选项。按照惯例,双破折号标记选项的结束。GNUgetopt识别双破折号并停止解析,并将其余部分作为位置参数返回。
参见:

i5desfxk

i5desfxk2#

我正在做一个类似的事情,发现这可以阻止getopt错误用这些错误来打扰我。基本上只是管道的错误遗忘。

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

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

yduiuuwa

yduiuuwa3#

对于getopt,至少对于util-linux-2.37.2中的一个,可以忽略STDERR或使用--quiet标志:

$ getopt --quiet --options=c: --longoptions=component -- --component value --foo
--component -- 'value'

请注意,退出状态仍然是1,因为getopt不能对参数进行验证,因为它不知道您想要忽略哪种错误。

0s7z1bwu

0s7z1bwu4#

如果你只想忽略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
pcrecxhr

pcrecxhr5#

我可以解决这个问题。这个想法涉及到在面对未知选项时摆弄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)),适应您自己的情况。这个假设被证明是脆弱和不包容的,但在这些情况下是有效的。还请注意,在出现错误(缺少参数)的情况下,它仍然会中断。
显然,这不是一个普遍和干净的方法,但有助于克服没有其他选择的情况。

相关问题