だから、私は学習体験として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、文字列の場合は=)を使用していることと、EVERYオプションがその "x"を除いて機能するという事実を組み合わせて使用していると確信しています。
どんな助けでも大歓迎です。ありがとう。
追伸-望ましい結果を達成するための別の方法は非常に高く評価されていますが、それでも、これが私の教育に役立たない理由を知りたいのです。再度、感謝します。
M/mまたはX/xと入力すると、-eq
を使用して非数値を数値と比較しているため、エラーが発生しています。 $opt
を文字列にしたい場合は、常に文字列として扱います。
...
if [ "$opt" = "1" ]; then
commands
Elif [ "$opt" = "2" ]; then
commands
...
@ Andyはすでに言っています の補足として、
[[ "$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
の現在の値に依存することにも注意してください。ユーザーから1行を読みたい場合は、次のようにします。
IFS= read -r opt
1文字を読み取るには:
IFS= read -rn1 opt
1つを読み取るにはWord(1行を読み取りますが、先頭のスペースとタブ、および最初のWord以外は無視してください):
IFS=$' \t' read -r opt ignored
または、バックスラッシュを前に付けることで、スペースまたはタブをWordに含めることができるようにします。
IFS=$' \t' read opt ignored