whileループの複数の条件[閉じる]

whileループの複数の条件[閉じる]

という変数がありますchoicechoicenullではなく同じになるまでyes値を入力するように求められますno

つまり、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やその他の機能が豊富なシェルでは、正規表現のマッチングも使用できます。

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

または、少なくともBashとZshで明示的に有効にする必要があるかもしれないkshスタイルの拡張グローブ:

# 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" ]]
  }
)

2つのメソッドとメソッドを使用してオブジェクトタイプを宣言し、次の操作を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 $choiceis yesornoなので、明らかに空ではないからです。

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

もっと理解できるでしょう。

Kornシェル(またはまたはzsh -o kshglob)を使用して、次のこともできますbash -O extglobbash4.1+

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

答え3

これをテストする他の方法はありますか?

標準設定が利用可能ですcase

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

whileこれは構造がやや混乱する可能性がありますが、aの条件内でも機能します。

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

Javaと同じ方法ですか?

いいえ

関連情報