I want to define a set of values for a single variable. E.g.
singleDigit={0,1,2,3,4,5,6,7,8,9}
If the user gives 10 it should exit with an error.
How can this be achieved without using a loop, but an array instead?
I want to define a set of values for a single variable. E.g.
singleDigit={0,1,2,3,4,5,6,7,8,9}
If the user gives 10 it should exit with an error.
How can this be achieved without using a loop, but an array instead?
If you want to store several values into a variable, that's where you'd use an array like:
allowed_values=(0 1 2 3 4 5 6 7 8 9)
Or
allowed_values=({0..9})
with bash3+ (syntax borrowed from zsh now also available in ksh93).
And if you want to check whether a given string is among any of those values, you could define a function like:
isin() {
local s
for s in "${@:2}"; do
[[ $1 = "$s" ]] && return 0
done
return 1
}
if isin "$input" "${allowed_values[@]}"
(in zsh, you can do if ((allowed_values[(eI)$input]))).
Note that the comparison is lexical (as in 01 != 1). Do do numerical comparison, you'd use [ "$1" -eq "$s" ] 2> /dev/null (note that 010 is 10, not 8). Do not use [[ $1 -eq $s ]] or ((s == $1)) as those introduce arbitrary command injection vulnerabilities.
If you want to assign a pattern to a variable to match against some input, you'd use a scalar variable and use one of the 2 (3 with the extglob option) pattern syntaxes supported by bash:
wildcard/glob pattern
pattern='[0-9]'
Used as:
case $input in
($pattern) echo OK;;
(*) echo NOK
esac
or
if [[ $input = $pattern ]]; then
echo OK
else
echo NOK
fi
Extended Regular Expression:
regex='^[0-9]$'
used as:
if [[ $input =~ $regex ]]; then
echo OK
else
echo NOK
fi
In the general case, for values other than single-character ones, you'd use:
regex='^(one|two|three)$'
And for patterns, you'd need the extglob option:
shopt -s extglob
pattern='@(one|two|three)'
Another approach with bash4+, or ksh93 or zsh is to use an associative array:
With bash, ksh93:
typeset -A allowed_values
allowed_values=([one]=1 [two]=1 [three]=1)
if ((allowed_values[$input])); then
echo OK
else
echo NOK
fi
In zsh, same but the assignment syntax is:
typeset -A allowed_values
allowed_values=(one 1 two 1 three 1)
(note that with bash, you can't have the empty string as an allowed value).
allowed_valaues=({0..9}) not work on?
{x..y} was added in bash 3 (2004),
If only the numbers 0 through 9 are allowable as input, all you need is a simple IF statement.
#!/bin/bash
echo -n Please enter a single digit:
read single_digit
if [ $single_digit -lt 10 ]; then
echo Thanks for $single_digit
else
echo Screwball!!! I said SINGLE DIGIT!!
fi