linux - 这是写opts的正确方法吗

标签 linux bash shell command-line getopts

这是使用 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

最佳答案

如果你想解析选项,你有两个可用的选项:

  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

关于linux - 这是写opts的正确方法吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12846345/

相关文章:

linux - 如何在 Linux 中使用 grep 进行多个基于 '&' 的搜索

linux - 将文件 os.rename() 重命名为时间戳返回奇怪的字符串

linux - 空闲 5 分钟后切换桌面 (xprintidle) : crontab or daemon?

linux - 使用 awk 和 sed 从 STDIN 重新格式化并执行

linux - 在 bash 脚本中用多行文本替换模式

bash - shell 终端 session 中环境之间的共同点是什么?

python - 如何使用 `watch` 使用特定于 bash 的语法?

Linux : Rename files that ends with live. conf 到 dev.conf

java - 使用JAVA更改LINUX机器的IP地址

php - lampp 错误 403 - 禁止访问