Bash参数解析逻辑运行到无限循环

时间:2017-01-17 23:26:10

标签: bash shell command-line command-line-arguments

我有一个解析命令行参数的循环。如果-d或-b参数有参数,一切正常。但是当我在没有参数的情况下传递-d或-b时,脚本会进入无限循环。

# Parse command line input
while [ "$#" -gt 0 ]; do
  case "$1" in
    -d) DOMAIN="$2"; shift 2;;
    -b) BITS="$2"; shift 2;;
     *) die "unrecognized argument: $1"
  esac
done

如何在空参数上抛出错误?

3 个答案:

答案 0 :(得分:2)

如果您尝试移动超过列表中存在的值的数量,则shift n命令不会执行任何操作。这就是代码中无限循环的原因。

使用getopts是正确的做法,因为它为您提供了很大的灵活性。否则,您可以这样重写循环:

#!/bin/bash
# Parse command line input
d_flag=0
b_flag=0
while [ "$#" -gt 0 ]; do
  case "$1" in
    -d) 
        d_flag=1
        shift
        [[ $1 == -* ]] && continue # argument to -d not given
        DOMAIN=$1
        shift
        ;; 
    -b) 
        b_flag=1
        shift
        [[ $1 == -* ]] && continue # argument to -b not given
        BITS=$1
        shift
        ;;
     *) echo "unrecognized argument: $1"; exit 2;;
  esac
done

if [[ $d_flag = 1 && -z $DOMAIN ]]; then
    # handle error - option requires an argument
fi

if [[ $b_flag = 1 && -z $BITS ]]; then
    # handle error - option requires an argument
fi

答案 1 :(得分:1)

由于参数不足,班次失败。

但是,如果您将shell设置为对所有错误(使用set -e)失败,那么这个问题就会很明显。在许多情况下,通过避免静默失败并强制执行规则和错误检查,它使调试变得更加容易。 set -u导致失败的变量扩展出错,也非常有用。

答案 2 :(得分:0)

由于您似乎总是需要两个参数,因此可以将第一行更改为:

while [ "$#" -eq 2 ]; do

否则你可以在进入循环之前检查$ 2的值,如下所示:

if [[ -z $2 ]]; then 
echo "missing second parameter"
else
#do the while loop
fi