while 루프에 대한 여러 조건 [닫기]

while 루프에 대한 여러 조건 [닫기]

라는 변수가 있습니다 choice. choicenull이 아니고 같을 때까지 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" ]]
  }
)

두 개의 및 메소드를 사용하여 객체 유형을 선언한 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 yesor no이므로 분명히 비어 있지 않기 때문입니다.

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와 같은 방식인가요?

아니요

관련 정보