while循环的多个条件

while循环的多个条件

我有一个名为 的变量choice。我想提示输入一个值choice直到它非空且等于yesno

换句话说:当choice为空或不同时yes,然后no输入选择。

如果我用 Java 编写它,那将是小菜一碟:

while (choice.IsEmpty() || (!choice.equals("yes") && !choice.equals("no"))

shell但是如果不使用内容(双引号之间的 var)语法,我就找不到将其翻译成的方法:

while [ "$choice" != "yes" && "$choice" != "no" ]

显然它是有效的,但是,就我个人所知,是否有另一种方法可以像在 Java 中一样进行测试?

答案1

while [ "$choice" != "yes" && "$choice" != "no" ]

实际上不起作用,因为它&&破坏了[命令。使用以下任一方法:

while [  "$choice" != "yes" ] && [ "$choice" != "no" ]
while [[ "$choice" != "yes"   &&   "$choice" != "no" ]]

在 Bash 和其他功能丰富的 shell 中,您还可以使用正则表达式匹配:

while [[ ! $choice =~ ^(yes|no)$ ]]

或 ksh 风格的扩展 glob,可能至少需要在 Bash 和 Zsh 中显式启用:

# shopt -s extglob        # Bash, though not needed within [[ .. ]] 
                          #       in recent versions
# setopt kshglob          # Zsh
while [[ $choice != @(yes|no) ]]

或者在 Zsh 中,使用 Zsh 自己的扩展 glob 语法:

while [[ $choice != (yes|no) ]]

(参见例如这个答案 用于不同扩展全局之间的关系。)

答案2

While (choice.IsEmpty() || (!choice.equals("yes") && !choice.equals("no"))POSIX语法的直译sh如下:

while
  [ -z "$choice" ] || {
    ! [ "$choice" = yes ] &&
    ! [ "$choice" = no ]
  }
do
 ...
done

为了更接近匹配,您可以使用ksh93它对对象编程提供实验支持:

typeset -T java_string=(
  function IsEmpty
  {
    [[ -z $_ ]]
  }
  function equals
  {
    [[ $_ = "$1" ]]
  }
)

用两个and方法声明一个java_string对象类型,然后:IsEmptyequals

java_string choice
while
  IFS= read -r 'choice?Enter your choice: ' || exit
  choice.IsEmpty || {
    ! choice.equals yes &&
    ! choice.equals no
  }
do
  print -ru2 "Wrong choice: $choice, try again."
done

[ -z "$choice" ]是多余的,因为 if$choiceyesor no,显然它不为空。

until
  [ "$choice" = yes ] || [ "$choice" = no ]
do
  ...
done

会更有意义。

使用 Korn shell(或zsh -o kshglob或),您还可以执行以下操作bash -O extglobbash4.1+

until
  [[ $choice = @(yes|no) ]]
do
  ...
done

答案3

还有另一种方法可以测试吗

您可以使用标准case构造:

case $choice in yes|no) false ;; esac

即使在 a 的条件部分中也可以使用while,尽管结构可能会有点混乱:

while case $choice in yes|no) false ;; esac; do 

和Java中的方式一样吗?

相关内容