という変数がありますchoice
。choice
nullではなく同じになるまで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
行います。IsEmpty
equals
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 $choice
is yes
orno
なので、明らかに空ではないからです。
until
[ "$choice" = yes ] || [ "$choice" = no ]
do
...
done
もっと理解できるでしょう。
Kornシェル(またはまたはzsh -o kshglob
)を使用して、次のこともできますbash -O extglob
。bash4.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と同じ方法ですか?
いいえ