bash:满足条件时,while循环无法退出

时间:2020-08-29 06:43:49

标签: bash boolean-logic

我是bash的新手,而以下while循环使我发疯。我希望当用户输入y或n时退出循环,但这样做失败。我尝试了不同的方法,但是没有运气。任何人都可以指出我正确的方向吗?

    echo "want to go for a walk Y/N "
    read answer
    while [ "$answer" != "y" ]  ||  [ "$answer" != "n" ]  ; do 
               
        echo "Enter y or n"
        read answer
    done

第二种解决方案也是在相同的情况下

    echo "want to go for a walk Y/N "
    read answer
    while [ "$answer" != "y"   ||   "$answer" != "n" ]  ; do 
               
        echo "Enter y or n"
        read answer
    done

2 个答案:

答案 0 :(得分:2)

当然它不会退出。该循环永远不会。

在您的代码中,answer始终不是'y'或不是'n'(同时,一起)。

之所以这样,是因为如果您选择“ y”,则它不是“ n”;如果您选择“ n”,则它不是“ y”。

如果您有TRUE || FALSE = TRUE 而且如果您有FALSE || TRUE = TRUE,那么循环就继续进行。

您要使用的条件是&&(与),因此,answer不是'y'并且不是'n'时,请继续,但是如果它是其中之一,则退出。

TRUE && FALSE => FALSEFALSE && TRUE => FALSE,这就是循环最终结束所需要的。

#!/bin/bash

echo "want to go for a walk y/n "
read -r answer
while [ "$answer" != "y" ]  &&  [ "$answer" != "n" ]  ; do 
           
    echo "Enter y or n"
    read -r answer
done

-r中的read -r var标志是为了避免将反斜杠读取为转义字符。与此玩具问题无关,但包括它是最佳做法。

David的评论:请记住,代码无法处理大小写,因此Y不能识别为y。

答案 1 :(得分:0)

不要忘记在while循环中,第一个命令列表可能还包含多个语句:

#!/usr/bin/env sh

echo "want to go for a walk y/n "

while
  read -r answer
  case $answer in
    [yYnN]) false ;;
  esac
do
  echo "Enter y or n"
done

或者使用until和Bash的 E 扩展了 R 例如 E 表达式:

#!/usr/bin/env bash

echo "want to go for a walk y/n "

until
  read -r answer
  [[ $answer =~ [yYnN] ]]
do
  echo "Enter y or n"
done

以及一个不区分大小写的功能强大的POSIX兼容实现:

#!/usr/bin/env sh

echo "want to go for a walk y/n "

until
  read -r answer
  case $answer in
    [yY])
      echo "Handling Yes answer stuffs"
      ;;
    [nN])
      echo "Stuffs for No answer"
      ;;
    *)      # Landing here if invalid answer
      false # Proceed with the do...done statements
      ;;
  esac
do
  echo "Enter y or n"
done