Bash 在 if elif else 语句中使用逻辑与和或的脚本
Bash script with logical ands, and ors in an if elif else statement
我搜索并找到了很多 if elif 函数的示例,但是 none 我发现似乎还包括逻辑 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 语句变得如此复杂吗?期待这种水平的比较似乎并不过分乐观,是吗?
你应该使用 ||
和 &&
:
#!/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(文件),如果文件存在,returns 为真,但表达式 "$BASE" != ""
不是文件。
您应该使用逻辑 "and" 和 "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
您正在混合 [
又名 test
和 Bash 本身的语法。在 [
和 ]
之间,-a
是一个布尔 AND,但它只是这个特定命令的一个特性。
一般情况下,command1 && command2
只有command1
returns成功才会执行command2
,同理,command1 || command2
会执行command2
仅当 command1
returns 失败时。
所以你可以说
if [ condition1 -a condition2 ]
或
if [ condition1 ] && [ condition2 ]
但无论如何,您的代码看起来确实需要 case
。我在你的脚本逻辑上遇到了一些问题,但它可以简化很多,因为实际上没有 basename $PWD
可以是空字符串的情况(在根目录中,basename是 /
)。此外,在 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
我搜索并找到了很多 if elif 函数的示例,但是 none 我发现似乎还包括逻辑 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 语句变得如此复杂吗?期待这种水平的比较似乎并不过分乐观,是吗?
你应该使用 ||
和 &&
:
#!/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(文件),如果文件存在,returns 为真,但表达式 "$BASE" != ""
不是文件。
您应该使用逻辑 "and" 和 "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
您正在混合 [
又名 test
和 Bash 本身的语法。在 [
和 ]
之间,-a
是一个布尔 AND,但它只是这个特定命令的一个特性。
一般情况下,command1 && command2
只有command1
returns成功才会执行command2
,同理,command1 || command2
会执行command2
仅当 command1
returns 失败时。
所以你可以说
if [ condition1 -a condition2 ]
或
if [ condition1 ] && [ condition2 ]
但无论如何,您的代码看起来确实需要 case
。我在你的脚本逻辑上遇到了一些问题,但它可以简化很多,因为实际上没有 basename $PWD
可以是空字符串的情况(在根目录中,basename是 /
)。此外,在 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