如何使选项接受任意数量的参数



我正在尝试编写一个带有选项的 shell 脚本,这些脚本在每次运行中采用不同数量的值,例如

运行 1:

./myscript --input <file1> <file2> --output <folder1>

运行 2:

./myscript --input <file1> <file2> <file3> --output <folder1> <folder2>

我尝试使用getopts,如下所示:

while getopts ":i:o:" opt; do
case $opt in
i)
echo "treatment files are: $OPTARG" >&2
infiles="${OPTARG}"
;;
o)
echo "control files are: $OPTARG" >&2
outdir="${OPTARG}"
;;
?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done

但是,我发现为"-i"选项输入可变值量的唯一方法是通过引号("file1 file2"(,这会阻止我/用户使用命令行的自动完成功能来帮助生成文件路径。此外,此选项似乎不允许我使用"--input"语法来传递选项。

有人可以帮忙吗?

多谢。

你这里有两个问题。 其中之一是"如何在我的 shell 脚本中实现长选项?",这里有很好的阅读。

另一个问题是,"如何使选项接受任意数量的参数? 答案大多是"你没有"。 通常,最干净的解决方案是让您的脚本多次接受该选项,如下所示:

./myscript -i <file1> -i <file2> -i <file3>

通过附加到 Bash 数组,这相对容易处理,如下所示:

infiles=()
while getopts ":i:o:" opt; do
case $opt in
i)
infiles+=("${OPTARG}")
;;
esac
done

稍后,您可以遍历这些值:

for inputfile in "${infiles[@]}"; do
...
done

有关详细信息,请阅读 bash 数组。

如果您不喜欢该解决方案,则可以以类似于我在第一段中链接的问题的一些答案的方式实现自己的选项解析。这将允许你获得你想要的命令行语义,尽管我认为行为与典型程序的行为方式不一致。

最新更新