1에서 100 사이의 숫자를 표시하고 숫자가 범위를 벗어났는지 표시하는 방법은 무엇입니까? [폐쇄]

1에서 100 사이의 숫자를 표시하고 숫자가 범위를 벗어났는지 표시하는 방법은 무엇입니까? [폐쇄]
#!/bin/bash/  

echo "Choose a number between 1 and 100"  
read num  
num=num  
echo  
if [ $num -lt 100 -o -gt 1 ]; then  
       echo "You chose $num"  
elif [ $num -gt 100 -o -lt 1 ]; then  
       echo "you chose a number outside of the boundary"  
fi

답변1

POSIX sh 구문을 사용하십시오.

#! /bin/sh - 

printf 'Choose a decimal integer number between 1 and 100: '
IFS= read -r num

die() {
  printf >&2 '%s\n' "$@"
  exit 1
}
case $num in
  ("" | - | *[!0123456789-]* | ?*-*)
    die "$num is not a valid decimal integer number";;
  (*[123456789]??*)
    die "You chose a number outside the boundaries"
esac

if [ "$num" -lt 1 ] || [ "$num" -gt 100 ]; then  
  die "You chose a number outside the boundaries"
fi

echo "You chose $num"
  • 숫자모호하다. 0xAA, MMXVIII, ¾, 010, 1.4e+4, infinity는 모두 특정 정의에 따른 숫자입니다.숫자. 무엇보다도 POSIX와 유사한 많은 쉘은 bash내장에서 10진수 정수만 지원합니다 [(산술 표현식에서는 10진수, 8진수, 16진수). 정확히 어떤 유형의 번호를 원하는지 확인하는 것이 가장 좋습니다. 여기서는 십진 정수를 예로 들어 보겠습니다.
  • 산술 표현식에 임의 문자열을 사용하고 [명령에 특정 셸을 사용하는 것은 명령 주입 취약점입니다.. 따라서 입력한 숫자가 숫자처럼 보이는지 먼저 확인해야 합니다.
  • IFS= read -r line입력 줄을 읽는 구문입니다.( 여기서 $IFS-스트리핑 및 줄 연속 처리는 read num괜찮을 수 있지만).
  • 매개변수 확장은 Bourne과 같은 쉘에서 인용되어야 합니다.
  • 논리에 문제가 있습니다. 사용해 보셨나요?또는바꾸다그리고운영자. 모든 십진수는 1보다 크다또는100 미만.
  • -o및 연산자는 -a [안정적으로 해석할 수 없는 테스트 표현식을 생성하므로 더 이상 사용되지 않습니다. 여기서 인수가 십진 정수인지 확인하면 문제가 없으므로 사용하지 않는 것이 가장 좋습니다. 또는 쉘 연산자 [로 구분된 여러 호출을 사용하는 것이 가장 좋습니다 .&&||
  • stderr()에 오류 메시지를 인쇄 >&2하고 실패 시 0이 아닌 종료 상태로 종료하는 것이 더 좋습니다.
  • 대부분의 쉘은 컴파일러의 기본 정수 데이터 유형을 정수 연산자로 사용합니다. 대부분의 시스템에 있는 쉘의 경우, 예를 들어 2 64 +50 (18446744073709551666)은 이 내부 표현에 비해 너무 큽니다. 셸의 [구현에 따라 숫자로 인식되지 않거나(bash, dash, yash), 경고와 함께 19자리로 잘리거나(zsh), float로 근사화되거나(ksh93), 래핑되거나(따라서 다음과 동일하게 처리됩니다.) 50) (mksh). 따라서 [ 18446744073709551666 -gt 0 ]false를 반환하거나 [ 18446744073709551666 -le 100 ]true를 반환하는 것을 알 수 있습니다 . 따라서 *[123456789]??*숫자가 3자리 이상인지 확인하세요.
  • 사용자가 입력의 일부로 NUL 문자를 입력하면 다른 쉘은 다르게 동작합니다.

구체적으로 bash다음을 수행하면 약간 덜 어색하게 만들 수 있습니다.

#! /bin/bash - 

IFS= read -rp 'Choose a decimal integer number between 1 and 100: ' num

die() {
  printf >&2 '%s\n' "$@"
  exit 1
}
[[ $num =~ ^-?[0123456789]+$ ]] ||
  die "$num is not a valid decimal integer number"

[[ $num = *[123456789]??* ]] ||
  ((num < 1 || num > 100)) &&
  die "You chose a number outside the boundaries"

echo "You chose $num"

답변2

셸을 사용하여 테스트합니다.

#!/bin/bash
read -rp "Choose a number between 1 and 100: " num
echo  
if [ "$num" -le 100 -a "$num" -ge 1 ]; then  
       echo "You chose $num"  
else 
       echo "you chose a number outside of the boundary"  
fi

Bash 확장을 사용하여 테스트합니다.

#!/bin/bash
read -rp "Choose a number between 1 and 100: " num
echo  
if [[ "$num" -le 100 && "$num" -ge 1 ]]; then  
       echo "You chose $num"  
else
       echo "you chose a number outside of the boundary"  
fi

쉘 연산 사용:

#!/bin/bash
read -rp "Choose a number between 1 and 100: " num
echo  
if ((num<=100 && num>=1)); then  
       echo "You chose $num"  
else  
       echo "you chose a number outside of the boundary"  
fi

참고: 현재 -o사용 중인또는하지만 당신은 -a원하는 것 같아요그리고. 또는 조건만 전달해야 하므로 숫자는 -1 또는 101이 될 수 있습니다.

또한 우변은 -o완전히 새로운 테스트와 같기 때문에 해당 측에 대한 변수를 다시 도입해야 합니다. 또한 숫자가 첫 번째 테스트에 실패하면 다른 테스트를 수행할 필요가 없기 때문에 문 else대신 사용합니다 .elif

답변3

아래 두 번째 줄은 치명적인 오타(아마도 num="$num")이지만, 맞다면 그 줄은 불필요할 것입니다.

read num
num=num

사용자가 숫자를 입력하는 경우"1", 두 번째 줄은 숫자가 아닌 문자열로 변경합니다."숫자". 그러면 이후의 모든 수치 제한 확인이 중단됩니다.

이 문제를 해결하려면 두 번째 줄을 삭제하면 됩니다.

관련 정보