为什么我会得到预期的整数表达式?

为什么我会得到预期的整数表达式?

因此,我尝试在 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”之外,每个选项都有效。

任何帮助是极大的赞赏。谢谢。

PS - 非常感谢实现预期结果的替代方法,但即使如此,我也想知道为什么这对我的启发不起作用。再次感谢。

答案1

当您输入 M/m 或 X/x 时,您正在使用 比较非数字与数字-eq,这会导致失败。如果有时想$opt成为字符串,则始终将其视为字符串:

...
if [ "$opt" = "1" ]; then
    commands
elif [ "$opt" = "2" ]; then
    commands
...

答案2

作为补充@安迪已经说过了, 注意

[[ "$opt" = [m,M] ]]

匹配m,M。如果你想匹配mM仅匹配,那就是

[[ "$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

相关内容