我正在尝试编写一些代码,将一系列 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
时,它会返回一个空白。这些相同角色的其他选择会出现各种其他问题,如果人们认为这会有所帮助,我很乐意讨论这些问题。
您似乎以错误的方式解释了选项名称后面的两个冒号。语法
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' -- "$@")