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"

omar180791
  • 39
  • 1
  • 7
  • 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. – Stephen P Sep 22 '20 at 23:01
  • Sthephen You are the best, now it works correctly. Thank you!!! – omar180791 Sep 22 '20 at 23:38
  • made it an answer, if you want to accept it. – Stephen P Sep 22 '20 at 23:50

2 Answers2

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.

Stephen P
  • 14,422
  • 2
  • 43
  • 67
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.

lucasgrvarela
  • 351
  • 1
  • 4
  • 9