【问题标题】:Shell script with single choice options带有单选选项的 Shell 脚本
【发布时间】:2017-06-29 17:34:48
【问题描述】:

我想知道,是否可以使用不允许组合多个选项的 getoptgetopts 编写带有选项的 shell 脚本?

例如,我的脚本可以以两种可能的模式运行 - 长或短以及带有 alpha 或 beta 选项,这就是为什么我想使用 ./script.sh -l -a./script.sh -l -b./script.sh -s -a./script.sh -s -b,但它不能同时运行-l-s-a-b 这两个选项。

我知道它可以变得更容易,因为我可以让 option -a 运行 long version alphaoption -b 运行 long version betaoption -c 运行 short version alpha 和 @987654337 @ 将运行short version beta,但我想使用两个选项,只要了解这种方式是否可行。

请在下面找到带有“选项”的代码以选择使用简单的read,我想将其转换为getopt(s)

#!/bin/bash
echo "Please insert the text:"

read text 

echo

echo "You entered $text"

echo "Choose version:

1) Long
2) Short
3) Quit
-> "

read option

# OPTION 1 

if [ "$option" == "1" ]; then

echo "Choose method:

1) alpha
2) beta"

read method

# METHOD 1

if [ "$method" == "1" ]; then

longalpha

fi

# METHOD 2

if [ "$method" == "2" ]; then

longbeta

fi

fi

#OPTION 2

if [ "$option" == "2" ]; then

echo "Choose method:

1) alpha
2) beta"

read method2

# METHOD 1

if [ "$method2" == "1" ]; then

shortalpha

fi

# METHOD 2

if [ "$method2" == "2" ]; then

shortbeta

fi

fi

if [ "$option" == "3" ]; then

echo "Good Bye!"

fi

【问题讨论】:

  • -l-s 是否必须存在,如果使用它们是否应该都是第一个参数?
  • 两者中的任何一个都必须呈现,并且它是否是第一个使用的参数都没有关系。当只有-l-s 选项时,脚本不应该工作,必须有-l -a / -l -b / -s -a / -s -b。据我所知(我刚刚开始使用 shell 脚本),getoptgetopts 在代码中一个接一个地运行单独的选项,但如果有 -l -a,我想运行 script1,脚本 2如果有-l -b,脚本3如果有-s -a,脚本4如果有-s -b
  • @KoahNuttler:顺序重要吗? -a -l 无效吗?只是为了确认
  • @Inian:它不只是告诉脚本是否应该运行另一个更短的脚本或更长的脚本:脚本 a 的较长版本,脚本 a 的较短版本等。
  • 那么,您是在寻找纯粹在getopt(s) 中的解决方案吗?使用-l 设置long 标志和使用-s 设置short 标志并在处理所有参数后检查是否设置了两个标志并抱怨是不够的?

标签: bash shell options getopt getopts


【解决方案1】:

您应该首先解析所有选项,并设置变量指示哪些已通过,哪些未通过。

然后,在实际执行任何操作之前,测试-l-s 是否都存在或都缺失,如果存在则退出并显示相应的错误消息。

您可以使用-a-b 执行类似的检查

一旦您知道您拥有所需的一切,但仅此而已,您就可以让您的脚本执行适当的操作。

【讨论】:

  • 用代码向我们展示如何做到这一点会很有用。在其当前形式中,它只是一个 comment
  • OP的问题似乎不是如何编写工作代码(问题中没有代码,工作或不工作,因此难以提供相关示例代码),问题似乎确定编码所需行为的正确方法。这就是我描述一个想法而不是编写实际代码的原因。
  • 为了清楚我的意思,提供 OP 可以按照 SO 标准复制和粘贴的代码可能会提供更好的答案,但如果问题是关于期望的结果,在我看来,建议一种没有代码的方法可以构成答案而不是评论。
  • @KoahNuttler 请将您的代码放入问题中。
【解决方案2】:

运行getopts 时,您可以通过un设置表示该标志的变量来检查是否已经设置了独占标志。

假设您有两个变量将决定您想要做什么,并且它们开始未设置:

unset vers meth

您还有一个用于操作标志的查找表,例如:

declare -A flags=([l]=long [s]=short [a]=alpha [b]=beta)

然后你可以像这样运行getopts

while getopts "lsab" opt; do
    case $opt in
        (l|s) [[ $vers ]] && fail       # we already set $vers
              vers=${flags[$opt]} ;;
        (a|b) [[ $meth ]] && fail       # we already set $meth
              meth=${flags[$opt]} ;;
        ('?') fail ;;                   # we got some unknown option
    esac
done

剩下的唯一事情就是检查我们确实为$vers$meth 获得了一些东西

[[ $vers && meth ]] || fail

然后执行你的任务:

$vers$method

处理最后一部分的方式取决于代码的具体情况,但由于您调用的是shortalpha 等,因此这种方式非常适合。如果您改为调用一些外部代码,则可能是 prog --$vers --$meth 等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 2019-10-11
    • 1970-01-01
    相关资源
    最近更新 更多