我搜索并找到了很多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的ol'bash: [: too many arguments
错误,我似乎无法使其工作。bash脚本是否不喜欢它们的IF语句来获得这种复杂性?期待这种水平的比较似乎并不过于乐观,是吗?
您正在混合[
(也称为test
)和Bash本身的语法。在[
和]
之间,-a
是一个布尔and,但它只是这个特定命令的一个特性。
在一般情况下,只有当command1
返回成功时,command1 && command2
才会执行command2
,类似地,command1 || command2
只有在command1
返回失败时才执行command2
。
所以你可以说
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
您应该使用||
和&&
:
#!/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
问题在于比较,您使用的选项-a(File)在文件存在时返回true,但表达式"$BASE" != ""
不是File。
您应该使用逻辑"and"one_answers"or"而不是(-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