使用 getopts 读取作为最终位置放置的一个可选参数
Using getopts to read one optional parameter placed as final place
我写了一个 bash 脚本,它接受灵活数量的参数,现在我想为每个参数添加一个可选参数 (-l
)。
我目前很难获得所需的行为。
我希望正确执行以下所有操作:
./Script.sh arg1 arg2 arg3 -l opt
./Script.sh arg1 arg2 arg3
./Script.sh arg1 arg2 arg3 arg4 -l opt
./Script.sh arg1 arg2 arg3 arg4 arg5
问题是无法设置$OPTIND
。
如果将 -l opt
放在第一个参数之前,则以下循环有效。
while getopts ":l:" option
do
case "$option" in
t)
F_NAME=$OPTARG
;;
esac
done
shift $((OPTIND - 1))
但是,将可选的 -l
作为最后一个参数是必需的。
实现此目标的最简单方法是什么?
getopts
符合 posix 标准命令行语法,其中标志选项在前。所以非标准情况下不好用
但是,您可能有 getopt(1)
的 Gnu 实现(参见 man 1 getopt
),它可以处理置换选项标志和长选项。但是,它不是一个简单的界面。
或者你可以自己解释这个论点。
for ((i=1; i<=$#; ++i)); do
if [[ ${!i} == "-l" ]]; then
((++i))
OPT_L=${!i}
else
# handle the argument (in "${!i]")
fi
done
(注意:如果 -l
出现在参数列表的末尾,上面不会抛出错误;它只是将选项值设置为空字符串。如果那不合适,它可能不是,然后插入一些错误检查。)
这是我发现的一个技巧,可以在 getopts 中使用带有可选参数的参数。
Jan Schampera 在 bash-hackers.org :
中给出了管理可选参数在命令中的情况的方法
if [[ $OPTARG = -* ]]; then
((OPTIND--))
continue
fi
(参见:http://wiki.bash-hackers.org/howto/getopts_tutorial 页面深处)
但它不管理在命令末尾给出选项的情况。
在那种情况下,这被认为是错误的,因为没有给出参数,getopts
将 opt
变量设置为 ':'(冒号)和OPTARG
到故障选项值。
所以我们必须用 case $OPTARG
.
来处理 ':' 的情况
假设我们编写了一个具有三个选项的脚本:
a
: 没有参数
b
: 需要一个参数
v
:设置 详细程度 的值从 0
到 2
。默认值为 0
,当使用 -v
不带参数或错误值调用脚本时使用预设值。
这是代码:
#!/bin/bash
VERBOSITY=0 # default verbosity set to 0
PRESET_VERBOSITY=1 # preset verbosity when asked
while getopts :ab:v: opt; do
case $opt in
a)
echo "manage option a"
;;
b)
echo "manage option b with value '$OPTARG'"
;;
v)
if [[ $OPTARG = -* ]]; then # Jan Schampera reply
echo "set verbosity to PRESET (no value given, not last position)"
VERBOSITY=$PRESET_VERBOSITY
((OPTIND--))
continue
fi
if [[ "$OPTARG" =~ ^[0-2]$ ]]; then
echo "set verbosity to $OPTARG (good value given)"
VERBOSITY=$OPTARG
else
echo "set verbosity to PRESET (bad value given)"
VERBOSITY=$PRESET_VERBOSITY
fi
;;
:)
case $OPTARG in
v)
echo "set verbosity to PRESET (no value given, last option)"
VERBOSITY=$PRESET_VERBOSITY
;;
esac
;;
\?)
echo "WTF!"
;;
esac
done
echo "**verbosity is set to $VERBOSITY**"
我写了一个 bash 脚本,它接受灵活数量的参数,现在我想为每个参数添加一个可选参数 (-l
)。
我目前很难获得所需的行为。
我希望正确执行以下所有操作:
./Script.sh arg1 arg2 arg3 -l opt
./Script.sh arg1 arg2 arg3
./Script.sh arg1 arg2 arg3 arg4 -l opt
./Script.sh arg1 arg2 arg3 arg4 arg5
问题是无法设置$OPTIND
。
如果将 -l opt
放在第一个参数之前,则以下循环有效。
while getopts ":l:" option
do
case "$option" in
t)
F_NAME=$OPTARG
;;
esac
done
shift $((OPTIND - 1))
但是,将可选的 -l
作为最后一个参数是必需的。
实现此目标的最简单方法是什么?
getopts
符合 posix 标准命令行语法,其中标志选项在前。所以非标准情况下不好用
但是,您可能有 getopt(1)
的 Gnu 实现(参见 man 1 getopt
),它可以处理置换选项标志和长选项。但是,它不是一个简单的界面。
或者你可以自己解释这个论点。
for ((i=1; i<=$#; ++i)); do
if [[ ${!i} == "-l" ]]; then
((++i))
OPT_L=${!i}
else
# handle the argument (in "${!i]")
fi
done
(注意:如果 -l
出现在参数列表的末尾,上面不会抛出错误;它只是将选项值设置为空字符串。如果那不合适,它可能不是,然后插入一些错误检查。)
这是我发现的一个技巧,可以在 getopts 中使用带有可选参数的参数。
Jan Schampera 在 bash-hackers.org :
中给出了管理可选参数在命令中的情况的方法 if [[ $OPTARG = -* ]]; then
((OPTIND--))
continue
fi
(参见:http://wiki.bash-hackers.org/howto/getopts_tutorial 页面深处) 但它不管理在命令末尾给出选项的情况。
在那种情况下,这被认为是错误的,因为没有给出参数,getopts
将 opt
变量设置为 ':'(冒号)和OPTARG
到故障选项值。
所以我们必须用 case $OPTARG
.
假设我们编写了一个具有三个选项的脚本:
a
: 没有参数b
: 需要一个参数v
:设置 详细程度 的值从0
到2
。默认值为0
,当使用-v
不带参数或错误值调用脚本时使用预设值。
这是代码:
#!/bin/bash
VERBOSITY=0 # default verbosity set to 0
PRESET_VERBOSITY=1 # preset verbosity when asked
while getopts :ab:v: opt; do
case $opt in
a)
echo "manage option a"
;;
b)
echo "manage option b with value '$OPTARG'"
;;
v)
if [[ $OPTARG = -* ]]; then # Jan Schampera reply
echo "set verbosity to PRESET (no value given, not last position)"
VERBOSITY=$PRESET_VERBOSITY
((OPTIND--))
continue
fi
if [[ "$OPTARG" =~ ^[0-2]$ ]]; then
echo "set verbosity to $OPTARG (good value given)"
VERBOSITY=$OPTARG
else
echo "set verbosity to PRESET (bad value given)"
VERBOSITY=$PRESET_VERBOSITY
fi
;;
:)
case $OPTARG in
v)
echo "set verbosity to PRESET (no value given, last option)"
VERBOSITY=$PRESET_VERBOSITY
;;
esac
;;
\?)
echo "WTF!"
;;
esac
done
echo "**verbosity is set to $VERBOSITY**"