4

I am using Regexes in Bash Shell script. I am using the below Regex code to check password criteria : Password should be at least 6 characters long with at least one digit and at least one Upper case Alphabet. I validated in the Regex validation tools, the Regex I have formed works fine. But, it fails in Bash Shell Script. Please provide your thoughts.

echo "Please enter password for User to be created in OIM: "
echo "******Please Note: Password should be at least 6 characters long with one digit and one Upper case Alphabet******"
read user_passwd
regex="^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)\S{6,}$"
echo $user_passwd
echo $regex
if [[ $user_passwd =~ $regex ]]; then
    echolog "Password Matches the criteria"
else
    echo "Password criteria: Password should be at least 6 characters long with one digit and one Upper case Alphabet"
    echo "Password does not Match the criteria, exiting..."
    exit
fi
2
  • 1
    A single regular expression isn't necessarily the best solution for this kind of problem. As you can see from anubhava's answer, a series of tests that correspond directly to your requirements can be simpler and easier to maintain. Commented Dec 30, 2013 at 19:01
  • 1
    Your regexp checks for at least one lower case letter, but you don't mention that requirement in your question. Commented Dec 30, 2013 at 19:02

2 Answers 2

5

BASH regex engine doesn't support lookarounds as in your regex.

You can use following shell glob check to make sure password matches your criteria:

[[ ${#s} -ge 6 && "$s" == *[A-Z]* && "$s" == *[a-z]* && "$s" == *[0-9]* ]]

It will make sure that input string $s meets all these conditions:

  • at least 6 characters long
  • has at least one digit
  • has at least one Upper case Alphabet
  • has at least one Lower case Alphabet
Sign up to request clarification or add additional context in comments.

9 Comments

Just for the sake of clarity, I'd write >= 6 rather than > 5. BTW, the question didn't mention a requirement for at least one lower case letter.
Yes >= 6 is better. I saw OP's regex "^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)\S{6,}$" that was checking for lowercase character as well.
In my testing both 123AsaA and 123AsaA came as valid passwords.
Hi Anubhava, Thank you so much for the answer. New Learning for me here. I have one doubt here (hope I dont sound too dumb) I entered range of inputs i.e. the length of the input (ranging from 6-12), the above code works between the length of input between 6-10 but after 10, the control moves to else condition and fails. Please let me know if there is any specific reason for it? Input provided: Success : aas12A AsaA123 123AssaA AAAsss123 Failed: aaaSSSAAA1 aaaSSSAAA112
ok can you post the code you tried in your question then I can certainly test it out and suggest you accordingly.
|
1

I'm adding to anubhava's answer. His check worked for me but not completely. For e.g. "hello123" or "HELLO123" also passed the check, so it didn't detect case. The issue was with the locale settings, more specifically the LC_COLLATE variable. It needs to be set to "C" to consider case. But a better solution was to use character classes rather than range expressions. The explanation here helped me to solve my problem. Eventually using character classes worked for me.

[[ ${#s} -ge 6 && "$s" == *[[:lower:]]* && "$s" == *[[:upper:]]* && "$s" == *[0-9]* ]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.