Getopt 看到了我未包含在命令中的额外“--”参数

问题描述 投票:0回答:1

我正在尝试编写一些代码,将一系列 conda 工具和一些我自己的 python 代码结合在一起。我提供了一些 getopt 选项,但它们解析得很奇怪。我希望能够以任何顺序提供选项,并且我希望可以使用短选项和长选项。我提供了定义默认选项以及主要 getopt 部分的代码。这是相关的代码片段:

seq_tech=''
input=''
outfolder='ProkaRegia'
threads=$(grep ^cpu\\scores /proc/cpuinfo | uniq |  awk '{print $4}')

is_positive_integer() {
    re='^[0-9]+$'
    if ! [[ $1 =~ $re ]] ; then
       return 1
    fi
    if [ "$1" -le 0 ]; then
        return 1
    fi
    return 0
}
...

ARGS=$(getopt -o i:o::t::s:c::h:: -l 'input:,output::,threads::,seq_tech:,clean::,help::' -n 'prokaregia.sh' -- "$@")
eval set -- "$ARGS"

echo "All arguments: $@"

if [[ $# -eq 1 ]]; then
    usage
fi

while [[ $# -gt 0 ]]; do
    case $1 in
        -i|--input)
            input="$(readlink -f "$2")"
            echo "$2"
            shift 2
            ;;
        -o|--output)
            output=$2
            shift 2
            ;;
        -t|--threads)
            if is_positive_integer "$2"; then
                threads=$2
                shift 2
            else
                echo "Error: Thread count must be a positive integer."
                exit 1
            fi
            ;;
        -s|--seq_tech)
            if [[ $2 == "ont" || $2 == "pacbio" ]]; then
                seq_tech=$2
                shift 2
            else
                echo "Error: Sequencing technology must be either 'ont' or 'pacbio'."
                exit 1
            fi
            ;;
        -c|--clean)
            clean_option=true
            shift
            ;;
        -h|--help)
            usage
            ;;
        *)
            echo "Error: Invalid option $1"
            exit 1
            ;;
    esac
done

但是,运行以下命令时:

bash prokaregia.sh -t 2 -i prokaregia.dockerfile

我得到以下回报:

All arguments: -t  -i prokaregia.dockerfile -- 2
Error: Thread count must be a positive integer.

is_positive_integer
在命令行中完美运行(感谢 chatgpt!),将命令行选项更改为
"--input"
"--threads"
会产生相同的行为,就像更改顺序一样。我相当确定问题来自于参数列表中生成额外双连字符的任何内容。它还会生成额外的空白,因为当我在
echo "$2
函数中尝试
threads
时,它会返回一个空白。这些相同角色的其他选择会出现各种其他问题,如果人们认为这会有所帮助,我很乐意讨论这些问题。

bash flags getopt
1个回答
0
投票

您似乎以错误的方式解释了选项名称后面的两个冒号。语法

t::
does not 表示“选项
-t
是可选的”,它的意思是“选项
-t
接受一个可选参数”。所有选项都被认为是可选的,您应该检查自己是否提供了强制选项。

至于为什么参数没有被解析,这看起来像是

getopt
的一个奇怪的怪癖。如果选项带有可选参数(选项名称后面有两个冒号
::
),则
getopt
仅识别沿选项本身指定的参数,且两者之间没有空格。例如
-t2
--threads=2
有效,而
-t 2
--threads 2
则无效。

对于强制参数,但这似乎不会发生,您可以编写任何

-t2
-t 2
--threads 2
--threads=2
并获得相同的结果。

我不认为你想要可选的选项参数,所以只需删除你添加的所有附加冒号,一切都应该按你的意愿工作:

ARGS=$(getopt -o i:o:t:s:ch -l 'input:,output:,threads:,seq_tech:,clean,help' -n 'prokaregia.sh' -- "$@")
© www.soinside.com 2019 - 2024. All rights reserved.