如何在你的shell使用互斥的标志,并添加一个可选的参数标志(套牢getopts的) [英] How to use mutually exclusive flags in your shell and add an optional argument flag ( stuck with getopts)

查看:327
本文介绍了如何在你的shell使用互斥的标志,并添加一个可选的参数标志(套牢getopts的)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是标准的getopts的逻辑。但我想我怎样才能使我优惠 - 互相排斥的选项。
例如

I am using a standard getopts logic. But I want to how I can make the options I offer- mutually exclusive. e.g.

shell.sh -a SID 
                              <accepted>
shell.sh -b SID
                              <accepted>
shell.sh -ab SID 
               Message- using ab together is the same as running shell.sh     without   any   options supplying  just SID . Help usage < ya da ya > 
shell.sh 
                Please enter SID at the minimum. Usage < ya da ya >
shell.sh SID
               <accepted>

我试图开发使用类似下面这样的逻辑

I am trying to develop this logic using something like below

while getopts ":a:b:" opt; do
  case $opt in
  a ) SID="$OPTARG";;
      set var=1
  b ) SID="$OPTARG";;
      set var=2

 \?) echo "Invalid option: -"$OPTARG"" >&2
        exit 1;;
  ) echo "Option -"$OPTARG" requires an argument." >&2
        exit 1;;
  esac
done

If  (( val == 1 ))  then ; # option a is invoked SID supplied 
<stuff>
elif  (( val == 2 )) then ; # option b is invoked SID supplied 

<stuff>

else # SID supplied but neither a or b is invoked 
<stuff>
fi

如何加强相互排斥的标志。我肯定有更多的杂技演员的方式来做到这一点。我想我在这里失去了一些东西常识 - 并试图找出答案。
THX

How do enforce mutually exclusive flags. I a sure there are more acrobat ways to do it. I think I am missing something commonsense here - and trying to figure that out . Thx

$ more opt.ksh
die () {
    echo "ERROR: $*. Aborting." >&2
    return  1
}

var=
while getopts ":a:b:" opt; do
  case $opt in
      a ) SID="$OPTARG"
          [ "$var" = 2 ] && die "Cannot specify option a after specifying option b"
          [ "$OPTARG" = b ] && die "Do not specify b as a value for option a"
          var=1
          ;;
      b ) SID="$OPTARG"
          [ "$var" = 1 ] && die "Cannot specify option b after specifying option a"
          [ "$OPTARG" = a ] && die "Do not specify a as a value for option b"
          var=2
          ;;
      :)  die "Must supply an argument to $OPTARG"
          ;;
      \?) die "Invalid option: -$OPTARG. Abort"
          ;;
  esac
done
shift $(($OPTIND - 1))
[ "$SID" ] || SID=$1
[ "$SID" ] || die "You must, at the minimum, supply SID"

我使用KSH

$ ps -p $$
  PID TTY          TIME CMD
 1261 pts/45   00:00:00 ksh

1时我运行它。

1st time I run it .

$ . opt.ksh -a 123 -b 123  # c0
ERROR: Cannot specify option b after specifying option a. Aborting.
-bash: /home/d1ecom1/gin1: No such file or directory


$ . opt.ksh -ab 123  # c1 should reject "cant use a and b togather. try with a or b"
-nologin: .[25]: shift: 4: bad number
$ . opt.ksh -a -b  # c2  same as c1's message
$ . opt.ksh -a -b 123 # c3 same as c1

$ . opt.ksh -a -b 123  # c5 
$ . opt.ksh -ab 123    # c6
$ . opt.ksh -a 123 -b 123  # c7

所有上述情况C0:C7应该拒绝。通知C0和C7是相同的。然而,这C0的inspite给出了预期的错误和C7不会给任何错误?奇怪

All above cases C0:C7 should reject. Notice C0 and C7 are the same. Yet inspite of this C0 gives the expected error and C7 will not give any error ? strange

唯一的工作应该是

. opt.ksh -a 123
. opt.ksh -b 123
. opt.ksh  123

@hvd:TYSM您的回复。
我想补充产生额外标志-p,将给予路径覆盖选项。
所以也许我们不得不延长getopt的采取这样的参数

@hvd :TYSM for your reply. I would like to add an additonal flag -p that will give a "path override" option. so maybe we have to extend getopt to take parameters like this

    die () {
    echo "ERROR: $*. Aborting." >&2
    exit 1
}

var=
opta=false
optb=false
while getopts ":ab:p" opt; do
  case $opt in
      a ) $optb && die "Cannot specify option a after specifying option b"
          opta=true
          ;;
      b ) $opta && die "Cannot specify option b after specifying option a"
          optb=true
          ;;
      p )  [ -d "$mypath" ] && die "path is invalid"

          ;;

      \?) die "Invalid option: -$OPTARG. Abort"
          ;;
  esac
done
shift $(($OPTIND - 1))
test $# -eq 0 && die "You must supply SID"
test $# -eq 1 || die "Too many command-line arguments"
# SID=$1

以上是老的做法。现在,我有2个输入参数。一个是SID和另一个是路径。它是那么简单,上面还是我需要更多的检查添加到prevent其他不需要的组合。这个问题我想我想瞄准的是,更多的条款将需要做出以允许该-p参数是一个optiona override参数是什么。 - P可以共存上述任何参数,但后来我想一个要求是它应立即-p标志以下
所以这不应该允许 - 因为它的不明确

The above was the old approach. Now I have 2 Input parameters. One is the SID and the other is the path. Is it as simple as the above or do I need to add more checks to prevent other unwanted combinations. The question I guess I am trying to aim at is , what more provisions would need to be made to allow this -p parameter which is an optiona override parameter. - p can co-exist with any parameter above but then I guess one requirement is that it should be immediately following the -p flag so this should not allow - because its not clear .

shell.sh -b -p 123 /home/yadaya

再次感谢

推荐答案

下面是你如何能做到这一点而不进行SID的选项参数,这使得我更有意义:

Here's how you can do it without making SID an option argument, which makes more sense to me:

die () {
    echo "ERROR: $*. Aborting." >&2
    exit 1
}

var=
opta=false
optb=false
while getopts ":ab" opt; do
  case $opt in
      a ) $optb && die "Cannot specify option a after specifying option b"
          opta=true
          ;;
      b ) $opta && die "Cannot specify option b after specifying option a"
          optb=true
          ;;
      \?) die "Invalid option: -$OPTARG. Abort"
          ;;
  esac
done
shift $(($OPTIND - 1))
test $# -eq 0 && die "You must supply SID"
test $# -eq 1 || die "Too many command-line arguments"
SID=$1

我所做的变化是:

The changes I've made are:


  • 收益1 变成退出1 (无关你的问题,但死亡听起来像它不应该继续)。 收益1 只会使死亡函数返回非成功,但调用死亡不检查其结果是,它会继续考虑。

  • getopts的字符串:AB 而不是:A:B:。不管你怎么称呼你的脚本,你总是需要传递只有一个SID,无论选择,所以它没有任何意义,我将它作为选项的部分。

  • 选项都存储在布尔 OPTA optb 更容易检查
  • 变量
  • 后,所有选项都通过了,剩下的命令行参数进行计数。除非是只有一个,调用脚本是无效的。

  • return 1 becomes exit 1 (unrelated to your question, but die sounds like it shouldn't continue). return 1 would merely make the die function return non-successfully, but the calls to die don't check its result, it would carry on regardless.
  • The getopts string is :ab instead of :a:b:. No matter how you call your script, you always need to pass exactly one SID, regardless of options, so it doesn't make sense to me to include it as part of the options.
  • The options are stored in boolean opta and optb variables for easier checking
  • After all options are passed, the remaining command-line arguments are counted. Unless it's exactly one, the call to the script is invalid.

在这个问题你所有的有效来电被接受,所有的无效问卷被拒绝。一个值得注意的这个兴趣,虽然:你的测试用例C7( -a 123 -b 123 )预计将失败,并没有失败,但不能因为 -a -b 组合。相反,在我的方法,因为 -b 将出现一个非选项参数之后,它本身就是一个非选项参数,以及拒绝的原因就变成了太多的命令直插式的论点。

All your valid calls in the question are accepted, all the invalid ones are rejected. One note of interest about this, though: your test case c7 (-a 123 -b 123) is expected to fail, and does fail, but not because -a and -b are combined. Instead, in my approach, since -b appears after a non-option argument, it itself is a non-option argument, and the reason for rejecting it becomes "Too many command-line arguments".

这篇关于如何在你的shell使用互斥的标志,并添加一个可选的参数标志(套牢getopts的)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆