그래서 학습 경험으로 bash에서 메뉴 시스템을 만들어 보았습니다. 이 작업을 수행할 수 있는 방법은 셀 수 없이 많으며 심지어 "더 나은" 방법도 있을 것이라고 확신합니다. 하지만 제가 가진 방법은 다음과 같습니다.
echo "
2nd Menu
********
1) command
2) command
M) Main menu
X) Exit program
"
read -p "Choose option >" opt
if [ "$opt" -eq 1 ]; then
commands
elif [ "$opt" -eq 2 ]; then
commands
elif [[ "$opt" = [m,M] ]]; then
main #calls the function main()
elif [[ "$opt" = [x,X] ]]; then
exit
else
echo "Invalid option"
main
fi
이 스크립트는 "X) 프로그램 종료"를 제외한 모든 옵션에서 작동합니다. "X" 또는 "x"를 실행하면 이 오류가 발생합니다...
./acct-mgr.sh: line 10: [: x: integer expression expected
./acct-mgr.sh: line 12: [: x: integer expression expected
Invalid option
이것은 나를 혼란스럽게 한다! 나는 각 데이터 유형(정수의 경우 -eq, 문자열의 경우 =)에 대해 올바른 비교 연산자를 사용하고 있으며 "x"를 제외한 모든 옵션이 작동한다고 확신합니다.
어떤 도움이라도 대단히 감사하겠습니다. 감사해요.
추신 - 원하는 결과를 얻을 수 있는 다른 방법을 알려주시면 감사하겠습니다. 하지만 그럼에도 불구하고 이것이 왜 제 경험적 방법에는 적용되지 않는지 알고 싶습니다. 다시 한 번 감사드립니다.
답변1
M/m 또는 X/x를 입력하면 숫자가 아닌 숫자를 숫자와 비교하므로 -eq
오류가 발생합니다. 가끔 문자열이 되고 싶다면 $opt
항상 문자열로 처리하세요.
...
if [ "$opt" = "1" ]; then
commands
elif [ "$opt" = "2" ]; then
commands
...
답변2
보충제로@앤디가 이미 말했어요, 알아채다
[[ "$opt" = [m,M] ]]
m
, 및 .,
일치 하고 일치만 M
하고 싶다면 다음과 같습니다.m
M
[[ "$opt" = [mM] ]]
여기서는 표준 구성을 사용하겠습니다 case
.
case $opt in
(1) commands;;
(2) commands;;
(m|M) main;;
(x|X) exit;;
(*) echo >&2 "Invalid option"; main
esac
또한 의 동작은 의 read
현재 값에 따라 달라집니다 $IFS
. 사용자로부터 행을 읽으려면 다음을 사용할 수 있습니다.
IFS= read -r opt
문자 읽기:
IFS= read -rn1 opt
가서 하나 읽어봐단어(한 줄을 읽으되 선행 공백과 탭 및 첫 번째 단어를 제외한 모든 항목은 무시합니다):
IFS=$' \t' read -r opt ignored
또는 다음에서 사용을 허용합니다.단어백슬래시 접두사를 추가하면 다음과 같습니다.
IFS=$' \t' read opt ignored