检查 bash 脚本的任何参数是否与字符串匹配

ima*_*453 95 linux unix bash shell-script

我正在尝试编写一个脚本,我想检查传递给 bash 脚本的任何参数是否与字符串匹配。我现在设置的方式是

if [ "$3" != "-disCopperBld" -a "$4" != "-disCopperBld" -a "$5" != "-disCopperBld" -a "$6" != "-disCopperBld"]
Run Code Online (Sandbox Code Playgroud)

但可能有大量参数,所以我想知道是否有更好的方法来做到这一点?

谢谢

编辑:我尝试了这段代码,并使用选项 -disableVenusBld 调用了脚本,但它仍然打印出“开始构建”。难道我做错了什么?提前致谢!

while [ $# -ne 0 ]
do
    arg="$1"
    case "$arg" in
        -disableVenusBld)
            disableVenusBld=true
            ;;
        -disableCopperBld)
            disableCopperBld=true
            ;;
        -disableTest)
            disableTest=true
            ;;
        -disableUpdate)
            disableUpdate=true
            ;;
        *)
            nothing="true"
            ;;
    esac
    shift
done

if [ "$disableVenusBld" != true ]; then
    echo "Starting build"
fi
Run Code Online (Sandbox Code Playgroud)

Nor*_*ray 75

看起来您正在 shell 脚本中进行选项处理。这是成语:

#! /bin/sh -

# idiomatic parameter and option handling in sh
while test $# -gt 0
do
    case "$1" in
        --opt1) echo "option 1"
            ;;
        --opt2) echo "option 2"
            ;;
        --*) echo "bad option $1"
            ;;
        *) echo "argument $1"
            ;;
    esac
    shift
done

exit 0
Run Code Online (Sandbox Code Playgroud)

(有几个缩进 的约定;;,一些 shell 允许您提供选项 as (--opt1),以帮助括号匹配,但这是基本思想)

  • 当预先不知道命令的参数数量时,使用 `shift` 语句,例如当用户可以提供任意数量的参数时。在这种情况下,参数在一个“while”循环中处理,测试条件为“$#”。只要参数数量大于零,此条件就为真。`$1` 变量和 `shift` 语句处理每个参数。每次执行 `shift` 时参数的数量都会减少,最终变为零,此时 `while` 循环退出。[来源](http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_07.html) (4认同)

Ric*_*lka 56

这对我有用。它完全按照您的要求执行,仅此而已(无选项处理)。无论这是好是坏都是海报的练习:)

if [[ "$*" == *YOURSTRING* ]]
then
    echo "YES"
else
    echo "NO"
fi
Run Code Online (Sandbox Code Playgroud)

这利用了对$* bash super-test [[...]]括号的特殊处理。

  • 您的意思是使用 =~ 运算符吗?否则我不明白为什么这应该起作用,而且当我尝试确切的脚本时它确实不起作用。 (9认同)
  • 像我这样的菜鸟请注意:YOURSTRING 可能会被引用,但星号必须在引号之外,例如 `if [[ "$*" == *"my search string"* ]]` (8认同)
  • 这个答案在过去四年里一直是错误的,因为 h7r 的编辑打破了它。原始答案(我现在已恢复)有效,前提是“您的字符串”不包含 glob 字符,并且有一些误报。例如,如果命令是“创建新证书”,而“你的字符串”是“猫”,这将报告匹配,因为“证书”*包含*“猫”。 (6认同)
  • 不工作。`bash -c 'echo args=$*; [[ "$@" == "bar" ]] && echo YES || echo NO' -- foo bar` (3认同)
  • 恕我直言,这必须是最正确的答案,因为该问题只需要检查参数的存在。但是,我已编辑将 `$*` 更改为 `$@`,因为要测试的字符串可能有空格并添加了指向 bash 相关文档的链接。 (2认同)
  • 这将整个参数列表与“你的字符串”进行比较。我认为您需要按照 [this answer](http://stackoverflow.com/a/28263100) 的建议进行操作。即:`bash -c 'echo args=$*; 对于 i 在 "$@" ; do [[ $i == "bar" ]] && echo "已设置!" && 休息 ; done' -- bar foo` 会起作用。 (2认同)
  • 直到我阅读@velis 评论并意识到 *YOURSTRING* 需要那些星号,这才起作用。为了清楚起见,也许编辑答案? (2认同)

Ric*_*ich 9

如何搜索(使用通配符)整个参数空间:

if [[ $@ == *'-disableVenusBld'* ]]
then
Run Code Online (Sandbox Code Playgroud)

编辑:好的,好的,所以这不是一个受欢迎的答案。这个怎么样,太完美了!:

if [[ "${@#-disableVenusBld}" = "$@" ]]
then
    echo "Did not find disableVenusBld"
else
    echo "Found disableVenusBld"
fi
Run Code Online (Sandbox Code Playgroud)

Edit2:好的,好的,也许这并不完美......认为它只有在 -param 位于列表的开头时才有效,并且也会匹配 -paramXZY 或 -paramABC。我仍然认为原始问题可以通过 bash 字符串操作很好地解决,但我在这里还没有完全破解它...... -你能吗??


use*_*765 7

[[ "$@" =~ '-disableVenusBld' ]] && disableVenusBld=true
[[ "$@" =~ '-disCopperBld'    ]] && disCopperBld=true
[[ "$@" =~ '-disableTest'     ]] && disableTest=true
[[ "$@" =~ '-disableUpdate'   ]] && disableUpdate=true
Run Code Online (Sandbox Code Playgroud)

或者更一般地说

[[ "$@" =~ 'your-string' ]] && ( doSomething )
Run Code Online (Sandbox Code Playgroud)

2023 年 12 月编辑:解决下面的评论,使用锚点进行精确匹配(可读性稍差,但惊喜较少):

#!/bin/bash

[[ "$*" =~ ^-disableVenusBld$ ]] && disableVenusBld=true
[[ "$*" =~ ^-disCopperBld$    ]] && disCopperBld=true
[[ "$*" =~ ^-disableTest$     ]] && disableTest=true
[[ "$*" =~ ^-disableUpdate$   ]] && disableUpdate=true
Run Code Online (Sandbox Code Playgroud)