如何在bash中“打破”if循环?

8
当我在bash中使用if循环中的break时,它告诉我对于bash无效,我应该使用什么代替?
使用情况是,用户被问及一个问题,如果他回答“否”,则脚本应跳过到下一部分。
if [[ $ans1_1 = "y" ]]; then
    fedoraDeps
elif [[ $ans1_1 = "n" ]]; then
    break
else
    echo "Answer 'y' or 'n' "
fi

在某些情况下,例如当条件使用文件系统时,不检查“if elif ..elif else fi”模式的所有条件将非常有用。 - user1767316
4个回答

21

if语句不是"循环结构",因此从中跳出没有意义。如果你想让其中一个block什么也不做,你可以使用内置的:命令,它仅仅是什么也不做。

if [[ $ans1_1 = y ]]; then
    fedoraDeps
elif [[ $ans1_1 = n ]]; then
    :
else
    echo "Answer 'y' or 'n'"
fi

有意义的做法是避免在某些情况下测试if then elif elif ... fi结构的所有条件,例如当条件调用文件系统时。 - user1767316

4

对于这个例子,我认为使用case更合适。

case $ans1_1 in
    y)fedoraDeps;;
    n);;
    *) echo "Answer 'y' or 'n'";;
esac

来自man bash

如果使用了 ;; 运算符,在第一次模式匹配后不会尝试任何后续的匹配。


1
这看起来更加简洁易于维护。我会更新我的脚本,使用 case 语句代替。谢谢。 - dominique120

1

我认为使用大小写转换可能是最好的选择。但无论如何,你应该将其转换为大写或小写。根据你的方式:

if [[ ${ans1_1,,} = "y" ]]; then
   fedoraDeps
elif [[ ${ans1_1,,} = "n" ]]; then
   :
else
   echo "Answer 'y' or 'n' "
fi

或者,如果您想要大写 ${ans1_1^^}。

0

这似乎是使用 select 命令的理想情况:

PS3="Please make a selection   >"
select foo in 'y' 'n'; do
    case $foo in
        'Y')
            fedoraDeps
            ;;
        'y')
            fedoraDeps
            ;;
        'n')
            break
            ;;
     esac
done

1
但这不意味着用户必须输入“1”表示是,“2”表示否,而不是正常的“y”/“n”输入吗?这似乎对于此目的来说过于复杂了。 - ruakh
公平地说,12yn一样复杂,但如果目标是持续询问直到做出有效选择,那么select是最好的工具之一。 - DopeGhoti
被呈现出 1) y2) n,并且必须输入 12 而不是 yn,肯定比简单地输入 y/n 更加复杂。我不知道你怎么会有不同的感受。 - ruakh
break 只在 循环 中有意义... ifcase 不是循环。在这种情况下,应该使用 :(什么也不做)或者在 case 语句中可以简单地删除 break 行。 - DJCrashdummy
顺便提一下:正如@Coder-guy在他的答案中简要提到的那样,我会使用case "${foo,,}" in来避免维护两个相同的情况。 - DJCrashdummy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接