测试Bash中是否存在一个参数

12

我想测试是否在我的bash脚本中传递了一个参数(例如-h)。

在Ruby脚本中,可以这样实现:

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

如何在Bash中最好地完成这个任务?


可能是[ bash shell 脚本检查输入参数 ]的重复问题 (https://dev59.com/cWw15IYBdhLWcg3wo9Vx)。 - Thomas
@Thomas -- 这个检查是否存在任何参数 -- 我认为这个问题是在询问特定的参数是否存在。 - Software Engineer
4个回答

10
最简单的解决方案是:
if [[ " $@ " =~ " -h " ]]; then
   echo "Has -h"
fi

1
虽然聪明,但是对于包含子字符串-h的字符串参数(例如my_command "oh gods -h game over"),此方法会报告错误的结果。唯一通用的解决方案是按照下面详细说明的方式迭代getopts结果。</shrug> - Cecil Curry
今天我也会推荐使用getopts。简单的解决方案更像是一个奇怪的hack... - kitingChris

3
#!/bin/bash
while getopts h x; do
  echo "has -h";
done; OPTIND=0

正如Jonathan Leffler指出的那样,使用OPTIND=0将重置getopts列表。这是为了防止需要多次执行测试的情况发生。

1
选项未被移除。重新解析参数列表的技巧是在getopts循环之间重置OPTIND=0 - Jonathan Leffler
明白了。验证过了。答案已经更正。感谢Jonathan Leffler提供的所有提示,这些提示帮助我得出了正确的答案。 - Aleksandr Levchuk
1
请注意,对于我来说,这会多次输出“has -h”,即使“-h”只被指定为一个参数... - logidelic

2

这个问题比较复杂,最快的方法也不可靠:

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 "$@"

等等。


0

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

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

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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接