【问题标题】:Is this the correct way to write opts这是编写 opts 的正确方法吗
【发布时间】:2012-10-02 12:26:07
【问题描述】:

这是获取和设置 OPTS 的正确方法吗?

我希望能够接受很多选择,例如

./runthis.sh --option1 setuff --option2 setmorestuff

while :
do
        case $1 in
                -h | --help | -\?)
                        usage
                        exit 0
                        ;;
                -o | --option1)
                        O=$2
                        shift 2
                        ;;
                -z | --option2)
                        Z=$2
                        shift 2
                        ;;
                --) # End of all options
                        shift
                        break
                        ;;
                -*)
                        echo "WARN: Unknown option (ignored): $1" >&2
                        shift
                        ;;
                *)  # no more options. Stop while loop
                        break
                        ;;
        esac
done

【问题讨论】:

标签: linux bash shell command-line getopts


【解决方案1】:

如果您想解析选项,您有两个现成可用的选项:

  1. getopts(您可以查看此教程的 getopts 教程)
  2. 手动解析(我将在这里介绍)

使用 getopts 可能更容易,但不够灵活。您的代码大部分是正确的,但不适合更一般的选项解析。

  1. 正如 chepner 所说,while truewhile : 相同。前者是首选,因为它可以立即直观地看到它在做什么。这是我们正在谈论的 bash,而不是 perl。无需进行不必要的混淆。
  2. while true 不是解析选项的良好循环终止条件。如果你仔细想想,它不会告诉你循环在做什么。我必须一直到你的最后一个案例才能了解发生了什么。正确的循环终止条件是命令行参数用完。
  3. 我们的循环执行任何形式的统一循环并不是很明显。我必须阅读每个案例以查看您正在移动位置参数数组。由于您将在每次迭代中至少执行一个 shift,因此请执行此操作。
  4. 绑定到#2,使用*) 来检查循环终止不是一个好主意。空字符串将匹配:

    ./foo.sh --option1 "" --option2 123

    如您所见,option2 永远不会使用您的代码获得它的价值。幸运的是 #2 也能解决这个问题。

  5. 最后一点:您可能应该引用所有变量,除非您确定它们不会包含空格。 bash 中的空格拆分发生在变量替换之后,所以空格真的会搞砸你。如果您不确定,请引用它。

您的代码的修订版本可能是:

while [ $# -gt 0 ]
do
        case "$1" in
                -h | --help | -\?)
                        usage
                        exit 0
                        ;;
                -o | --option1)
                        O="$2"
                        shift
                        ;;
                -z | --option2)
                        Z="$2"
                        shift
                        ;;
                --) # End of all options
                        shift
                        break
                        ;;
                *)
                        echo "WARN: Unknown option (ignored): $1" >&2
                        break
                        ;;
        esac
        shift
done

【讨论】:

    猜你喜欢
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    相关资源
    最近更新 更多