如何在 bash 中组合 getopts 和位置参数?
How to combine getopts and positional parameters in bash?
我想同时使用 getopts
和位置参数,但是如果我将位置参数传递给程序,getopts
就会丢失。
directory=
while getopts l: flag; do
case "$flag" in
l) level=$OPTARG;;
esac
done
if [ -n "$level" ]; then
echo "Level exist!"
else
echo "Level doesn't exist!"
fi
所以当我运行这样的程序时:
sh myprogram.sh ~/documents -l 2
我预计:
Level exist!
而是 returns:
Level doesn't exist!
问题是,如果我 运行 没有位置参数 (~/documents) 的程序是这样的:
sh myprogram.sh -l 2
我得到正确的输出:
Level exist!
这是为什么?如何在 bash 中同时使用位置参数和 getopts
?
谢谢!
大多数工具的编写形式为:tool [options] arg ...
所以你会这样做:
# first, parse the options:
while getopts l: flag; do
case "$flag" in
l) level=$OPTARG;;
\?) exit 42;;
esac
done
# and shift them away
shift $((OPTIND - 1))
# validation
if [ -n "$level" ]; then
echo "Level exist!"
else
echo "Level doesn't exist!"
fi
# THEN, access the positional params
echo "there are $# positional params remaining"
for ((i=1; i<=$#; i++)); do
printf "%d\t%s\n" $i "${!i}"
done
如果用户提供未知选项或未能提供所需参数,请使用 \?
中止脚本
并像这样调用它:
$ bash test.sh
Level doesn't exist!
there are 0 positional params remaining
$ bash test.sh -l 2
Level exist!
there are 0 positional params remaining
$ bash test.sh -l 2 foo bar
Level exist!
there are 2 positional params remaining
1 foo
2 bar
$ bash test.sh -x
test.sh: illegal option -- x
$ bash test.sh -l
test.sh: option requires an argument -- l
但是你不能将选项放在参数之后:getopts 在找到第一个非选项参数时停止
$ bash test.sh foo bar -l 2
Level doesn't exist!
there are 4 positional params remaining
1 foo
2 bar
3 -l
4 2
我想同时使用 getopts
和位置参数,但是如果我将位置参数传递给程序,getopts
就会丢失。
directory=
while getopts l: flag; do
case "$flag" in
l) level=$OPTARG;;
esac
done
if [ -n "$level" ]; then
echo "Level exist!"
else
echo "Level doesn't exist!"
fi
所以当我运行这样的程序时:
sh myprogram.sh ~/documents -l 2
我预计:
Level exist!
而是 returns:
Level doesn't exist!
问题是,如果我 运行 没有位置参数 (~/documents) 的程序是这样的:
sh myprogram.sh -l 2
我得到正确的输出:
Level exist!
这是为什么?如何在 bash 中同时使用位置参数和 getopts
?
谢谢!
大多数工具的编写形式为:tool [options] arg ...
所以你会这样做:
# first, parse the options:
while getopts l: flag; do
case "$flag" in
l) level=$OPTARG;;
\?) exit 42;;
esac
done
# and shift them away
shift $((OPTIND - 1))
# validation
if [ -n "$level" ]; then
echo "Level exist!"
else
echo "Level doesn't exist!"
fi
# THEN, access the positional params
echo "there are $# positional params remaining"
for ((i=1; i<=$#; i++)); do
printf "%d\t%s\n" $i "${!i}"
done
如果用户提供未知选项或未能提供所需参数,请使用 \?
中止脚本
并像这样调用它:
$ bash test.sh
Level doesn't exist!
there are 0 positional params remaining
$ bash test.sh -l 2
Level exist!
there are 0 positional params remaining
$ bash test.sh -l 2 foo bar
Level exist!
there are 2 positional params remaining
1 foo
2 bar
$ bash test.sh -x
test.sh: illegal option -- x
$ bash test.sh -l
test.sh: option requires an argument -- l
但是你不能将选项放在参数之后:getopts 在找到第一个非选项参数时停止
$ bash test.sh foo bar -l 2
Level doesn't exist!
there are 4 positional params remaining
1 foo
2 bar
3 -l
4 2