检查参数的强制参数

检查参数的强制参数

我的脚本包含几个具有必需参数的参数:

while [ "$1" != "" ]; do
    case $1 in
        -f | --first )          shift
                                first=$1
                                ;;
        -s | --second )         shift
                                second=$1
                                ;;
        * )                     break
    esac
    shift
done

echo "first: "$first" second: "$second

这可以正常工作:

$ ./script.sh --first a --second b
first: a second: b

但是,当有人忘记参数的参数时,获取参数就会出错。

例如,这不起作用:

$ ./script.sh --first --second a
first: --second second: 

这很糟糕(第一个是 get,但第二个强制未处理):

$ ./script.sh --first a --second
first: a second: 

我尝试修改:

* )                     break

到:

* )                     echo "Bad arguments"
                        exit 1

在这种情况下有效(首先处理强制):

$./script.sh --first --second b
Bad arguments

但在这种情况下无法正常工作(不处理第二个):

$ ./script.sh --first a --second
first: a second: 

答案1

使用内置的外壳getopts。这使用 optstring,您可以在其中列出所有有效的选项字符以及它们是否需要参数(通过在选项字符后面加上:)。例如:

while getopts 'f:s:' opt; do
  case "$opt" in 
    f) first="$OPTARG" ;;
    s) second="$OPTARG" ;;

    :) usage 1 "-$OPTARG requires an argument" ;;
    ?) usage 1 "Unknown option '$opt'" ;;
  esac
done

shift $((OPTIND -1))

请注意,内置getopts不支持 --long 选项。如果这是一个要求,请使用包getopt中的程序util-linux- 不要使用任何其他版本,其他版本都有严重的缺陷。

TEMP=$(getopt -o 'f:s:' --long 'first:,second:' -n "$0" -- "$@")
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
eval set -- "$TEMP"

while true ; do
  case "$1" in
    -f|--first)    first="$2" ; shift 2 ;;
    -s|--second)   second="$2" ; shift 2 ;;
    --)            shift ; break ;; 
     *)            echo 'Internal error!' ; exit 1 ;;
  esac
done

笔记:

  • getopts(带有s)内置于 POSIX shell,是可移植的和标准的。
  • getopt(没有s)是非标准的,有几个相互冲突的版本,其中大多数都有严重的缺陷。util-linux如果您不关心可移植性,则可以安全地使用包中的版本。
  • 如果没有给出需要参数的选项,它们都会抛出错误。

答案2

发生这种情况是因为 无论案例的文本是什么,shift都会转移到$2$1脚本的确切目的尚不清楚,但例如,如果您想避免这种情况,您可以执行以下操作:

while [[ "$1" != "" && "$2" != -* ]]; do
    case $1 in
        -f | --first )          shift
                                first=$1
                                ;;
        -s | --second )         shift
                                second=$1
                                ;;
        * )                     break
    esac
    shift
done

echo "first: "$first" second: "$second

如果缺少参数,这将避免操纵。

输出示例:

$ ./script.sh --first a --second b
first: a second: b
$ ./script.sh --first --second b
first:  second: 

相关内容