Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux bash脚本的getopts中不允许有多个选项_Linux_Bash_Validation - Fatal编程技术网

Linux bash脚本的getopts中不允许有多个选项

Linux bash脚本的getopts中不允许有多个选项,linux,bash,validation,Linux,Bash,Validation,有如下bash脚本 #! /bin/bash usage() { echo -e "need help!" } while getopts ":a:b:h" OPTION do case $OPTION in a) printf "a option with value %s\n" $OPTARG ;; b) printf "b option with value %s\n" $OPTARG

有如下bash脚本

#! /bin/bash

usage()
{
  echo -e "need help!"  
}

while getopts ":a:b:h" OPTION
do
     case $OPTION in
     a)
        printf "a option with value %s\n" $OPTARG
        ;;
     b)
        printf "b option with value %s\n" $OPTARG
        ;;
     h)
        usage
        ;;
     ?)
        echo -e "No option selected"
       ;;
    esac
done

exit 0
上面的脚本使用不同的选项运行良好,但我想扩展它,使其不允许像下面的参数一样同时传递多个选项

$ ./test.bash -a 1 -b 2
a option with value 1
b option with value 2
“应该无效”意味着它在某种程度上给了我错误,比如
错误的语法
我通过以下方式实现了它,但它似乎很长,如下所示

#! /bin/bash
usage()
{
  echo -e "need help!"  
}

let "a_count=0"
let "b_count=0"
MY_ARG=""
while getopts ":a:b:h" OPTION
do
     case $OPTION in
     a)
        let a_count=1
        MY_ARG=$OPTARG
        ;;
     b)
        let b_count=1
        MY_ARG=$OPTARG
        ;;
     h)
        usage
        ;;
     ?)
        echo -e "No option selected"
       ;;
    esac
done

[[ $a_count -eq 1 ]] && [[ $b_count -eq 1 ]] && echo "wrong command sytax" && exit 0

[[ $a_count -eq 1 ]] &&  printf "a option with value %s\n" $MY_ARG

[[ $b_count -eq 1 ]] &&  printf "b option with value %s\n" $MY_ARG

exit 0
奔跑

$ ./test.bash -a 1 -b 2
wrong command sytax
但是我想在
getopts
while..loop
中完成验证。此外,此验证不适用于以下命令

./test.bash -a -b 
a option with value -b

任何人都知道如何使用
getopts
进行这种类型的验证吗?

你几乎已经知道了。a后面和b后面的
表示它们接受了一个参数,因此您的
-a-b
示例实际上是有效的,表示“存在值为-b的选项a”

如果您真的只想要“-a或-b,然后是一个参数”,您可能根本不需要getopts,但应该:

[ "$1" == "-a" ] && printf "a option with value %s\n" $2
[ "$1" == "-b" ] && printf "b option with value %s\n" $2
有人知道如何使用getopts进行这种类型验证吗

实际上,您明确地告诉
geptopts
-a
-b
不是布尔参数,而是带有额外参数的参数。参数分析器无法判断下面的参数<代码> -A /代码>是一个参数还是它自己的参数,因此他们把[-a] [-b]看作语法。< /P> 实际上,最好的方法是在不需要
-a
-b
的参数时,使用与用例匹配的不同布尔参数

虽然,尝试使用参数或布尔值设置参数对您的问题没有帮助,但是对于参数语法检查,您可以尝试使用哪种更好的方法来创建命令行界面。您将重点放在编写
--help
文档上,它将解析文档以构建参数/参数解析器。e、 g:

eval "$(docopts -V - -h - : "$@" <<EOF
Usage: myscript [(-a <foo> | -b <bar> | -abool | -bbool)]

      -a <foo>   The A option.
      -b <bar>   The B option.
      -abool     The A bool
      -bbool     The B bool
      --help     Show help options.
      --version  Print program version.
----
myscript 0.0.0
Copyright (C)20.. Your Name
License...
)"

if $a ; then
    echo "a option! with $a"
fi

if $b ; then
    echo "b option! with $b"
fi

if $abool ; then 
    echo "abool option!"
fi


if $bbool ; then 
    echo "bbool option!"
fi

eval“$(docopts-V--h-:“$@”这不是很完美,因为它将始终处理第一个开关,但它确实在while循环中放置了一个出口,这符合您的设计要求。它可能会让您知道如何完成它

#!/bin/bash

usage()
{
  echo -e "need help!"
}

while getopts "a:b:h" OPTION
do
     case $OPTION in
     a)
       aflag=1
       aval=$OPTARG
       if [ ! -z "$bflag" ]
       then
         printf "ERROR: cant use both -a and -b\n"
         exit 1
       fi
       ;;
    b)
       bflag=1
       bval=$OPTARG
       if [ ! -z "$aflag" ]
       then
        printf "ERROR: cant use both -a and -b\n"
        exit 1
       fi
       ;;
    h) usage ;;
    ?) printf "ERROR" ; exit 1 ;;
   esac
done

if [ ! -z "$aflag" ]
then    
  printf "a option with value %s $aval\n"
elif [ ! -z "$bflag" ]
then
  printf "b option with value %s $bval\n"
fi

exit 0

如果您仍然想使用
getopts
,我将使用bash内置变量作为参数计数
$#
来检测传递的参数的错误数量:

#! /bin/bash

usage()
{
  echo -e "need help!"  
}

# Check if number of arguments is greater than 2 as "-a1" (one arg) and "-a 2" are correct.
# You might want to check for other wrong inputs.
if [ $# > 2 ]
then
    echo "Some warning t o the user or"
    usage
    exit 1
fi

while getopts ":a:b:h" OPTION
do
     case $OPTION in
     a)
        printf "a option with value %s\n" $OPTARG
        ;;
     b)
        printf "b option with value %s\n" $OPTARG
        ;;
     h)
        usage
        ;;
     ?)
        echo -e "No option selected"
       ;;
    esac
done

exit 0

是的,没有
getopts
这是可能的,但是我需要
getopts
,因为当前这里
-a
-b
选项后面会有更多,所以这种类型的条件会增加脚本长度,而且我需要在
while循环
之后在
while
中进行验证,无需进一步处理,正如您所述
所以你的-a-b的例子实际上是有效的
-b不是参数它是可选的,所以为什么
-a
-b
作为参数。不起作用,你看,当我发出命令
/test.bash-a-b
时,它会首先进入
a
的情况,其中
bflag
明显为零。所以总是给出输出,永远不要进入错误状态离子。试试看。它确实会因为while循环而产生错误。是的,当-a被计算时,bflag为零,但是while循环然后计算-b,aflag则不是零。但实际上我不认为你试图做的事情永远不会完美工作。你只能在while循环中处理动作或错误。一个或另一个都会有错误要在它之外处理。请查看我的编辑。错误现在被捕获在while循环中,之后处理的操作将被捕获。不,确实不起作用,我认为您需要首先检查它。请尝试命令
/test.bash-a-b
,然后查看输出。