如何检查 bash 脚本中的两个输入值是否正确?

如何检查 bash 脚本中的两个输入值是否正确?

我正在编写一个 bash 脚本,想要添加一些简单的验证测试。输入应该是1or2并且脚本应该再次要求输入,直到给出正确的输入。

我正在考虑使用until循环来做到这一点,但它不起作用。我绑定了until [ $group -eq 1 ]$group用户给出的值在哪里),但显然我还需要第二个输入。我怎样才能正确地做到这一点?

答案1

until
  printf 'Please enter 1 or 2: '
  IFS= read -r line || exit # exit on EOF
  [ "$line" = 1 ] || [ "$line" = 2 ]
do
  printf >&2 '"%s" is neither 1 nor 2, try again.\n' "$line"
done

使用IFS=-r,输入行将按原样存储在 中$line。您可能希望省略,以便自动从输入的开头或结尾删除IFS=空格(假设您没有修改)。$IFS

如果输入只能是12字符串,那么您需要使用=,而不是-eq

如果您想允许使用其他表达式12 数字,例如01, 1+1, 1.0, 100e-2, exp(0), RANDOM(有时),那么您可以使用-eq,但请注意,并非所有 shell 都接受上述所有类型的表达式(ksh93将接受所有类型,但bash仅接受诸如1(前导和/或尾随空白)之类的内容,或0001(前导零)),这意味着您将收到未形成有效算术表达式的输入的错误消息。

对于解释算术表达式的 shell,这也很危险,因为它可以更改变量值(例如对于像 之类的输入PATH=123),甚至运行任意命令(例如对于像 之类的输入a[0$(cmd>&2)])。

根据 shell 的不同,您还可能会在 18446744073709551617 或 4294967297(或 2 32或 2 64 + 1 或 2的任何其他倍数)上得到误报,因为大多数 shell 使用 64 位或 32 位整数。

无论你做什么,就做不是使用-oand-a二元test/[运算符。那些应该被驱逐它们使得命令的解析[可能不明确并且在实践中不可靠(现在被标记为过时的在 POSIX 规范中)

例如:

$ line='!' sh -c '[ "$line" = 1 -o "$line" = 2 ]'
sh: line 0: [: too many arguments

并记住引用您的变量("$line"而不是$line会进行 split+glob 的变量)。

答案2

这应该可行,将它们与或(-o)结合起来:

#init group variable
group=0
#read until value is either 1 or 2
until [ $group -eq 1 -o $group -eq 2 ]; 
    do 
    #your script...

    #read user input and put it in group
    read -p "Which group?" group 
done

您还可以使用||as 或 运算符:

until [ $group -eq 1 ] || [ $group -eq 2 ]

尽管在某些情况下,例如当您使用错误代码 ( $?) 时,第一个选项更好,请参阅这个答案

答案3

while IFS= read -r; do
    case "$REPLY" in
        1|2) break ;;
        *)   echo 'Error' >&2 ;;
    esac
done

此代码片段从标准输入读取一个值,然后针对1和进行测试2。如果匹配任一字符串,则循环退出,否则会生成简洁的诊断消息并继续循环。

答案4

只需使用以下命令将第二个条件添加到表达式中或者操作员-o

相关内容