【问题标题】:Bash test if an argument existsBash 测试是否存在参数
【发布时间】:2011-09-07 10:54:50
【问题描述】:

我想测试一个增强(例如 -h)是否已传递到我的 bash 脚本中。

在 Ruby 脚本中:

#!/usr/bin/env ruby
puts "Has -h" if ARGV.include? "-h"

如何在 Bash 中做到最好?

【问题讨论】:

标签: bash testing command-line-arguments


【解决方案1】:

我正在尝试以一种简单但正确的方式解决这个问题,并且只是分享对我有用的方法。

下面的专用函数解决了它,你可以这样使用:

if [ "$(has_arg "-h" "$@")" = true ]; then
    # TODO: code if "-h" in arguments
else
    # TODO: code if "-h" not in arguments
fi

此函数检查第一个参数是否在所有其他参数中:

function has_arg() {
    ARG="$1"
    shift
    while [[ "$#" -gt 0 ]]; do
        if [ "$ARG" = "$1" ]; then
            echo true
            return
        else
            shift
        fi
    done
    echo false
}

【讨论】:

    【解决方案2】:

    最简单的解决方案是:

    if [[ " $@ " =~ " -h " ]]; then
       echo "Has -h"
    fi
    

    【讨论】:

    • 虽然很聪明,但它会为嵌入子字符串 ` -h ` 的字符串的参数报告误报(例如,my_command "oh gods -h game over")。唯一的通用解决方案是迭代getopts 结果,详情如下。 </shrug>
    • 真的!今天我也会支持getopts。简单的解决方案更像是一个不稳定的黑客......
    【解决方案3】:

    它是适度复杂的。最快的方法也是不靠谱的:

    case "$*" in
    (*-h*) echo "Has -h";;
    esac
    

    不幸的是,这也会发现“command this-here”具有“-h”。

    通常你会使用getopts 来解析你期望的参数:

    while getopts habcf: opt
    do
        case "$opt" in
        (h) echo "Has -h";;
        ([abc])
            echo "Got -$opt";;
        (f) echo "File: $OPTARG";;
        esac
    done
    
    shift (($OPTIND - 1))
    # General (non-option) arguments are now in "$@"
    

    等等

    【讨论】:

      【解决方案4】:
      #!/bin/bash
      while getopts h x; do
        echo "has -h";
      done; OPTIND=0
      

      正如乔纳森·莱弗勒指出的那样 OPTIND=0 将重置 getopts 列表。这是为了防止测试需要进行多次。

      【讨论】:

      • 该选项未删除。重新解析参数列表的技巧是在 getopts 循环之间重置 OPTIND=0
      • 明白。已验证。答案更正。感谢 Jonathan Leffler 提供导致此答案的所有提示。
      • 请注意,对我来说,这会多次输出“has -h”,即使 -h 仅被指定一次作为参数...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-02
      • 2021-03-09
      相关资源
      最近更新 更多