There are a couple of issues in your code:
The #!
-line should read #!/bin/bash
(or whatever the full absolute path is to the bash
interpreter or your system). Note that you are using shell code that requires the use of bash
, so pointing the #!
-line to the sh
interpreter would not be correct as that shell may not understand things like the non-standard [[ ... ]]
, or the use of arrays.
Passwords should probably be read using IFS= read -s -r
in bash
to avoid echoing the input to the terminal, and to allow the use of \
without issues, and to allow flanking spaces etc.
Multiple tests are better written [ ... ] || [ ... ]
. This is what causes your actual error message. The [
utility does not know about ||
.
Suggestion:
#!/bin/bash
IFS= read -p 'Enter password: ' -sr password
check=(0 0)
[[ $password =~ [A-Z] ]] && check[0]=1
[[ $password =~ [a-z] ]] && check[1]=1
if [ "${check[0]}" = 1 ] || [ "${check[1]}" = 1 ]; then
echo yes
else
echo no
fi
Or, getting rid of the need for the array:
#!/bin/bash
IFS= read -p 'Enter password: ' -sr password
if [[ $password =~ [A-Z] ]] ||
[[ $password =~ [a-z] ]]
then
echo yes
else
echo no
fi
Note that testing the $password
string for matches of [A-Z]
or for matches of [a-z]
can be done in one test with [A-Za-z]
.
In the sh
shell, you could write your script like this:
#!/bin/sh
printf 'Enter password: ' >&2
state=$(stty -g) # save stty state
stty -echo # turn off local echo
IFS= read -r password
stty "$state" # reset stty state to original
case $password in
[A-Za-z])
echo yes
;;
*)
echo no
esac
Note that I've combined the tests for upper and lower case characters into a single test, and that the patterns used by case
are shell globbing patterns, not regular expressions.
If you need to check for upper and lower case letters, you still need the two separate tests:
case $password in (*[A-Z]*) check1=true;; (*) check1=false; esac
case $password in (*[a-z]*) check2=true;; (*) check2=false; esac
if "$check1" && "$check2"; then
echo yes
else
echo no
fi