带有逻辑ands的Bash脚本,以及if ifif else语句中的ors

时间:2015-04-15 07:02:40

标签: linux bash shell unix centos6

我已经搜索并找到了很多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

我得到了ol&#39; IF和ELIF都有bash: [: too many arguments错误,我似乎无法使其正常工作。 bash脚本不像它们的IF语句那样复杂吗?期待这种比较水平似乎并不过分乐观,是吗?

3 个答案:

答案 0 :(得分:0)

您应该使用||&&

#!/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

答案 1 :(得分:0)

问题在于比较,您使用的选项-a(File)如果文件存在则返回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

答案 2 :(得分:0)

您正在混合[又名test和Bash本身的语法。在[]之间,-a是布尔AND,但它只是此特定命令的一项功能。

在一般情况下,command1 && command2仅在command2成功返回时才会执行command1,同样,command1 || command2仅在command2时执行command1返回失败。

所以你可以说

if [ condition1 -a condition2 ]

if [ condition1 ] && [ condition2 ]

但无论如何,您的代码看起来确实需要case。我在脚本的逻辑上遇到了一些问题,但它可以简化很多,因为实际上没有basename $PWD可以是空字符串的情况(在根目录中,基本名称)是/)。此外,在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