在 if elif else 语句中具有逻辑与和 ors 的 Bash 脚本

Posted

技术标签:

【中文标题】在 if elif else 语句中具有逻辑与和 ors 的 Bash 脚本【英文标题】:Bash script with logical ands, and ors in an if elif else statement 【发布时间】:2015-06-21 00:35:06 【问题描述】:

我搜索并找到了很多 if elif 函数的示例,但我发现没有一个似乎也包含逻辑 AND 或 OR 运算符。

我在 bash 脚本中的以下 if 语句遇到问题:

#!/bin/bash

BASE="$(basename "$PWD")"
REPO="$(cut -d/ -f4 <<<"$PWD")"
if [ "$BASE" = "$REPO" ] -o [ "$BASE" = "" ]
then
  echo "[$REPO]"
elif [ "$REPO" = "" ] -a [ "$BASE" != "" ]
then
  echo "$BASE"
else
  echo "[$REPO] $BASE"
fi

我的 IF 和 ELIF 都出现了 bash: [: too many arguments 错误,我似乎无法让它工作。 bash 脚本不喜欢它们的 IF 语句来获得这种复杂性吗?期待这种水平的比较似乎并不过分乐观,是吗?

【问题讨论】:

ifelif 的末尾添加一个分号,在then 之前似乎没有什么区别。 【参考方案1】:

您正在混合 [ aka test 和 Bash 本身的语法。在[] 之间,-a 是一个布尔 AND,但它只是这个特定命令的一个特性。

一般情况下,command1 &amp;&amp; command2 将仅在 command1 返回成功时执行 command2,同样,command1 || command2 将仅在 command1 返回失败时执行 command2

所以你可以说

if [ condition1 -a condition2 ]

if [ condition1 ] && [ condition2 ]

但无论如何,您的代码看起来您​​实际上想要的是case。按照您的脚本逻辑,我遇到了一些问题,但可以简化很多,因为实际上没有basename $PWD可以是空字符串的情况(在根目录中,基本名称是@ 987654337@)。此外,在elif 分支中,您已经知道$BASE 不为空(暂时忽略它永远不会为空的事实),因为如果是,if 分支已经被占用了。

无论如何,假设您要检查我们是在 (a) 根目录还是正好向下四层的目录;或 (b) 在低于四级以下的非根目录中;或者 (c) 其他地方(这意味着目录向下五级或更多级),试试这个。因为case 将采用第一个匹配分支(请记住,如果必要,* 甚至会匹配在此上下文中包含斜杠的字符串),我不得不稍微重新排序。

case $PWD in
    /*/*/*/*/* )   # more than 4  (c)
        echo "[$REPO] $BASE" ;;
    / | /*/*/*/* )  # root or exactly 4  (a)
        echo "[$REPO"] ;;
    *)             # else, less than 4, not root  (b)
        echo "$BASE" ;;
esac

【讨论】:

谢谢,我最初使用这些运算符,但我的代码中存在其他问题,所以我一次更改了一堆东西,没有测试每个更改。 切换到case语句,完美运行。再次感谢!【参考方案2】:

您应该使用||&amp;&amp;

#!/bin/bash

BASE="$(basename "$PWD")"
REPO="$(cut -d/ -f4 <<<"$PWD")"
if [ "$BASE" = "$REPO" ] || [ "$BASE" = "" ]
then
  echo "[$REPO]"
elif [ "$REPO" = "" ] && [ "$BASE" != "" ]
then
  echo "$BASE"
else
  echo "[$REPO] $BASE"
fi

【讨论】:

【参考方案3】:

问题在于比较,您使用的是选项 -a(文件),如果文件存在则返回 true,但表达式 "$BASE" != "" 不是文件。

您应该使用逻辑“与”和“或”而不是 (-a, -o) 选项。

此代码适用于我:

#!/bin/bash

BASE="$(basename "$PWD")"
REPO="$(cut -d/ -f4 <<<"$PWD")"
if [ "$BASE" = "$REPO" ] || [ "$BASE"  = "" ]
then
  echo "[$REPO]"
elif [ "$REPO" = "" ] && [ "$BASE" != "" ]
then
  echo "$BASE"
else
  echo "[$REPO] $BASE"
fi

【讨论】:

以上是关于在 if elif else 语句中具有逻辑与和 ors 的 Bash 脚本的主要内容,如果未能解决你的问题,请参考以下文章

Python条件控制语句

if/elif/else 语句中的python 2.7.6 isupper 函数

lambda 中if-elif-if

如何在 Python 2.7 中评估 BASH-Like 命令 (if/elif/else) 语句

将 if-elif-else 语句放在一行上?

shell中的if语句逻辑错误