如何解析可选标志,无论它们在脚本调用中的位置和重复次数如何?

时间:2014-04-25 10:14:28

标签: bash shell parsing unix sh

我正在编写一个名为 stat 的BASH脚本,它需要以捕获重复和不同位置的方式解析其参数。 可以不带任何参数调用脚本,可选标志 -r ,并且可选文件名也作为参数传递给脚本,在本例中为 directory1

如何解析参数以便以下脚本调用有效?

./stat
./stat -r
./stat directory1
./stat -r directory1
./stat directory1 -r
./stat directory1 -r -r
./stat -r directory1 -r

到目前为止,我有办法解析 ./ stat -r directory1

recursive=0
while getopts ":r" opt; do
case $opt in
    r)
        recursive=1 
    ;;
    *)
                    echo "-$0: $opt is not a valid argument!"
        exit 1
    ;;
esac
done

这使我无法解析目录名,只输出目录名。

shift $((OPTIND-1)) #which removes processed options
echo "$*"

但是,如果我使用 ./ stat directory1 -r ./ stat -r directory1 -r ./ stat directory1 -r调用脚本-r ,参数未正确解析为 -r 标志后面的目录名被省略,未解析且未被 shift $((OPTIND-1)删除))电话。

所以,我想知道,我如何解析选项标记,以便捕获冗余的标记以及可能跟随 directory1 的标记。

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

正如您所发现的,getopts停在第一个非选项字。您被迫迭代所有参数:

dir="some default"
recursive=false
for arg; do
    if [[ $arg == "-r" ]]; then
        recursive=true
    else
        dir=$arg
    fi
done

使用" true"的优势和"假"像这样你可以写这个,因为truefalse是$ PATH上的程序:

if $recursive; then
    do_something_repeatedly
else
    do_something_once
fi

检查无效选项:

for arg; do
    case $arg in
        -r) recursive=true ;;
        -*) echo "invalid option: $arg" ;;
        *)  dir=$arg ;;
    esac
done