bash - 如何在 bash 脚本中为 if 条件组合 AND 和 OR 条件?

标签 bash unix if-statement

我试图在 if 条件下的 bash 脚本中组合逻辑 AND & OR。不知何故,我没有得到想要的输出,而且很难排除故障。 我正在尝试验证传递给 shell 脚本的输入参数是否没有参数以及传递的第一个参数是否有效。

if [ "$#" -ne 1 ] && ([ "$1" == "ABC" ] || [ "$1" == "DEF" ] || [ "$1" == "GHI" ] || [ "$1" == "JKL" ]) 
then
echo "Usage: ./myscript.sh [ABC | DEF | GHI | JKL]"
exit 1
fi

谁能指出这里出了什么问题?

最佳答案

你的陈述的直接问题是逻辑之一:你可能打算写:

if [ "$#" -ne 1 ] || ! ([ "$1" = "ABC" ] || [ "$1" = "DEF" ] || [ "$1" = "GHI" ] || [ "$1" = "JKL" ]) 
then
  echo "Usage: ./myscript.sh [ABC | DEF | GHI | JKL]" >&2
  exit 1
fi

即:如果给出了超过 1 个参数,或者如果给出的单个参数不等于可接受的值之一,则中止。

请注意 ! 来否定括号中的表达式,并使用符合 POSIX 标准的字符串相等运算符形式 =(而不是 == )。

但是,假设您使用的是 Bash,您可以使用单个 [[ ... ]] 条件和 Bash 的正则表达式匹配运算符 =~:

if [[ $# -ne 1 || ! $1 =~ ^(ABC|DEF|GHI|JKL)$ ]] 
then
  echo "Usage: ./myscript.sh [ABC | DEF | GHI | JKL]" >&2
  exit 1
fi

如果不需要符合 POSIX,对于 a variety of reasons[[ ... ]] 优于 [ ... ] . 在本例中,$#$1 不需要引号,|| 可以在内部 有条件的。

请注意,上面使用的 =~ 在 Bash 3.2+ 中有效,而在 anubhava's helpful answer 中使用的隐式 extglob 语法需要 Bash 4.1+;
但是,在早期版本中,您可以显式启用(并在之后恢复其原始值)extglob shell 选项:shopt -s extglob

关于bash - 如何在 bash 脚本中为 if 条件组合 AND 和 OR 条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38067413/

相关文章:

JAVA HashMap 重复

bash - 在 bash 中连接字符串

bash - 合并 CSV 文件 : Appending instead of merging

linux - 最小的 Linux 发行版

linux - 使用 wget 从 ftp 服务器下载选定的目录

java - 为什么我收到错误 'illegal start of type'

c++ - 关于 'char' 的奇怪程序行为

regex - Expect 和 shell 脚本中的正则表达式

bash - 从Docker容器A(在Docker容器B上)运行Bash脚本

bash - Bash的版本? —在Docker的构建上下文中