0

I'm trying to find the word "PASS_MAX_DAYS" in a file using grep grep "^PASS_MAX_DAYS" /etc/login.defs then I save it in a variable and compare it to a regular expression that has the value 90 or less.

regex = "PASS_MAX_DAYS\s*([0-9]|[1-8][0-9]|90)"

grep output is: PASS_MAX_DAYS 120

so my function should print a fail, however it matches:

function audit_Control () {

    if [[ $cmd =~ $regex ]]; then
        echo match
    else
        echo fail
    fi
}
cmd=`grep "^PASS_MAX_DAYS" /etc/login.defs`
regex="PASS_MAX_DAYS\s*([0-9]|[1-8][0-9]|90)"
audit_Control "$cmd" "$regex"

3
  • 1
    It appears bash =~ regex doesn't support the common escapes like \s (\\s?) -- try PASS_MAX_DAYS[[:space:]]*( etc ) instead. You might also want to add anchors ^PASS_MAX...(...)$ to make sure it's a whole-line match. Commented Sep 22, 2020 at 23:01
  • Sthephen You are the best, now it works correctly. Thank you!!! Commented Sep 22, 2020 at 23:38
  • made it an answer, if you want to accept it. Commented Sep 22, 2020 at 23:50

2 Answers 2

1

The problem is that the bash test [[ using the regex match operator =~ does not support the common escapes such as \s for whitespace or \W for non-word-characters.

It does support posix predefined character classes, so you can use [[:space:]] in place of \s

Your regex would then be:
regex="PASS_MAX_DAYS[[:space:]]*([0-9]|[1-8][0-9]|90)"

You may want to add anchors ^ and $ to ensure a whole-line match, then the regex is
regex="^PASS_MAX_DAYS[[:space:]]*([0-9]|[1-8][0-9]|90)$"

Without the end-of-line anchor you could match lines that have trailing numbers after the match, so PASS_MAX_DAYS 9077 would match PASS_MAX_DAYS 90 and the trailing "77" would not prevent the match.

This answer also has some very useful information about bash's [[ ]] construction with the =~ operator.

Sign up to request clarification or add additional context in comments.

Comments

0

I believe you have a problem with your regex, please try that version:

PASS_MAX_DAYS\s*([0-9]|[1-8][0-9]|90)$

[lucas@lucasmachine ~]$ cat test.sh 
#!/bin/bash

function audit_Control () {

    if [[ $cmd =~ $regex ]]; then
        echo match
    else
        echo fail
    fi
}
regex="PASS_MAX_DAYS\s*([0-9]|[1-8][0-9]|90)$"
audit_Control "$cmd" "$regex"
[lucas@lucasmachine ~]$ export cmd="PASS_MAX_DAYS 123"
[lucas@lucasmachine ~]$ ./test.sh 
fail
[lucas@lucasmachine ~]$ export cmd="PASS_MAX_DAYS 1"
[lucas@lucasmachine ~]$ ./test.sh 
match

I can explain the problem was the other regex was not checking the end of line, so, your were matching "PASS_MAX_DAYS 1"23 so 23 were not being "counted" to your regex. Your regex was really matching part of the text.. Now with the end of line it should match exactly 1 digit find a end of line, or [1-8][0-9] end of line or 90 end of line.

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.