0

I am trying some simple input validation in bash. Basically this part of my script outputs "press [index] to select [array element]." However I cannot seem to get it to stop and exit gracefully when an invalid input is entered. From my research so far this SHOULD work:

declare -a scenarios=()
scenarios+=("Scenario_123")
scenarios+=("Scenario_456")
scenarios+=("Scenario_789")

for i in ${!scenarios[@]}; do
    echo -e "select $i for ${scenarios[$i]}"
done
read ScenInd
echo ${#scenarios[@]} #[${ScenInd}=~^[0-9]+$, =~ ^[[:digit:]]+

if ! [${ScenInd}=~ ^[[:digit:]]+$  ] || [${ScenInd} < 0] || [${ScenInd} >= ${#scenarios[@]}];
    then
    echo "INVALID SELECTION"
    exit
fi

but when I run it and enter 8, I get '[8=~: command not found'

What have I done wrong and how do I fix this? I have tried this both with [${ScenInd}=~^[0-9]+$ and =~ ^[[:digit:]]+ yet the results are the same.

Thanks in advance

Andy
  • 207
  • 4
  • 18
  • 1
    Run your code through http://shellcheck.net/ and fix what it finds before asking questions here. – Charles Duffy Aug 22 '22 at 21:20
  • Note that `=~` is only valid in `[[ ]]`, not in `[ ]`, and you *must* have all these words separated by spaces. You can't run `[something` without a space any more than you can run `ls-l` without a space between the `ls` and the `-l`. Also, `<` isn't a comparison operator (when not quoted or escaped) in `[` either -- that too is a `[[` feature exclusively -- and moreover, it does _string_ comparisons, not _numeric_ comparisons. – Charles Duffy Aug 22 '22 at 21:21
  • Also, `echo -e` in general should not be used; even the POSIX standard for `echo` recommends using `printf` in all the circumstances where one might otherwise need it. See [Why is printf better than echo?](https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo) on [unix.se], and [the POSIX `echo` specification](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html), particularly the APPLICATION USAGE and RATIONALE sections. – Charles Duffy Aug 22 '22 at 21:24
  • ...one of the important things to understand about `[` is that it's a command. Literally, there's typically a `/bin/[` file on your disk (that's often a symlink or hardlink to `/bin/test`); the shell has a built-in copy of `[` too, but that's just a performance enhancement -- it's not syntax and is handled by the parser just like any other command, which is why `>` or `<` is treated like a redirection operator rather than an argument. – Charles Duffy Aug 22 '22 at 21:26
  • Finally -- think about checking `[[ ${array[$idx]} ]]`. A lot of what you're trying here is very unnecessarily overcomplicated, and also _doesn't work_ in interesting cases (like sparse arrays -- arrays in bash are actually more like maps than they are like what other languages call arrays; if they're associative the keys are strings, if they're indexed the keys are integers). – Charles Duffy Aug 22 '22 at 21:26
  • Thank you sir, I did not know about shellcheck, and your comments are very informative – Andy Aug 23 '22 at 13:11

0 Answers0