이 코드가 있는데 어떤 이유로 프로그램을 다시 시작해도 입력이 "예"로 인식되지 않습니다. 계속 "다시 주문하시겠습니까?" 라고 물어보네요. 무엇이 문제인 것 같은데(아마도 간단한 것일 수도 있지만) 잘 모르겠습니다.
#!/bin/sh
read -rp 'Fish or chicken? ' protein
read -rp 'Beans or rice? ' starch
read -rp 'Broccoli or asparagus? ' veggie
read -rp 'Beer or beer? ' drink
echo "You have ordered the $protein with a side of $starch and $veggie, and to drink you will have $drink"
while true; do
read -rp 'Would you like to order again? ' order
if echo "order" | grep -iq 'yes'; then
exec $0
elif echo "order" | grep -iq 'no'; then
exit 0
fi
done
또한 대답이 "예" 또는 "아니오"가 아닌 경우 인식하고 정답을 나타내는 줄을 인쇄하도록 하려면 어떻게 해야 합니까?
답변1
스크립트의 주요 문제점은 order
리터럴 문자열이 존재하는지 테스트한다는 것입니다 yes
. 아마도 "$order"
.
또 다른 문제는 를 사용하여 이 스크립트(스크립트 bash
) 를 실행한다는 것입니다 /bin/sh
. /bin/sh
POSIX 쉘 표준에 대한 일부 확장을 이해하지 못할 수도 있지만 bash
운이 좋을 수도 있습니다. 이를 사용 하려면 첫 번째 줄을 변경하십시오 bash
.
쉘 스크립트의 문자열 비교는 다음을 사용하여 수행할 수 있습니다.
if [ "$order" = "yes" ]; then ...; fi
이것은 "그리고 읽기 쉽다 grep
"라고 부르는 것보다 저렴합니다.
다음을 사용할 수도 있습니다 case ... esac
.
case "$order" in
yes) ... ;;
no) ... ;;
esac
다시 실행하기 위해 스크립트를 다시 실행하는 것은 불안정하고 매우 색다른 작업입니다. 예를 들어 스크립트가 bash script.sh
.
bash
select
다음과 같이 사용할 수 있는 루프 도 있습니다 .
echo 'Please select protein from this menu:'
select protein in "beans" "lentils" "tofu" "cheese"; do
if [ -z "$protein" ]; then
echo 'Invalid choice' >&2
else
printf 'You picked %s as protein\n' "$protein"
break
fi
done
이를 통해 사용자 입력을 더 효과적으로 제어할 수 있습니다.
사용자의 대화형 입력을 읽고 종료할지 묻는 일반적인 접근 방식은 다음과 같습니다.
while true; do
read -p 'Enter data: ' -r data
# use "$data" here for something
read -p 'Again? [Y/n] ' answer
case "$answer" in
[Nn]*) break ;;
esac
done
여기에 질문을 하고 일부 처리를 수행하는 외부 루프가 있습니다. 그런 다음 사용자에게 다시 갈 것인지 묻습니다. "아니요"( N
또는 로 시작하는 모든 항목 n
) 라고 대답하면 break
루프를 종료합니다.
최종 테스트는 검증일 수도 있습니다 $data
. 사용자가 처음에 잘못된 입력을 입력한 경우 read
유효한 입력이 제공될 때까지 다시 요청해야 할 수도 있습니다.
이것(또는 당신이 읽은 내용)의 장점은 $data
그것이 여전히 존재하고 입력 루프 이후에 사용 가능하므로 $data
루프 내부가 아닌 나중에 처리할 수 있다는 것입니다.
의사코드:
input-loop:
read-data
validate-data
if-valid exit input-loop
goto input-loop
main-code:
use-validated-data
답변2
order
다음 접두사를 붙여 $
역참조하는 것을 잊었습니다 .
#!/bin/sh
echo $0
read -rp 'Fish or chicken? ' protein
read -rp 'Beans or rice? ' starch
read -rp 'Broccoli or asparagus? ' veggie
read -rp 'Beer or beer? ' drink
echo "You have ordered the $protein with a side of $starch and $veggie, and to drink you will have $drink"
while true; do
read -rp 'Would you like to order again? ' order
if echo "$order" | grep -iq 'yes'; then
exec $0
elif echo "$order" | grep -iq 'no'; then
exit 0
fi
done
또한 간단히 문자열을 와 비교할 수도 있습니다 =
.