2

I want to compare the grep result with a varaiable. Here is my bash script

 check=$(grep "pam_wheel.so use_uid"  /etc/pam.d/su)
 result='#auth required pam_wheel.so use_uid'
        if [ "$check" =  "$result" ]; then
                echo "Access is not limited"
        else
                echo " limited access"       
        fi

How can i do it?. I tried many combinations but i couldn't get it working. Thanks in advance.

7
  • What is exact output of grep "pam_wheel.so use_uid" /etc/pam.d/su command? Commented Aug 29, 2014 at 8:05
  • As @skwllsp mention, your error is probably on the if condition where you assign (one egal sign) instead of testing egality (two egal signs) Commented Aug 29, 2014 at 8:18
  • Why do't you simply grep for the whole result string? Commented Aug 29, 2014 at 8:42
  • 1
    @skwllsp No, the single equal is the correct syntax, since it is compatible with sh, whereas bash recognizes both. Commented Aug 29, 2014 at 9:22
  • it is not working :( Commented Aug 29, 2014 at 9:40

3 Answers 3

3

The lines in /etc/pam.d/* are spaced to line up nicely. grep and test are spacing-sensitive (or rather, insensitive to any semantics of the bytes in the strings you want to compare) -- if the strings are not exactly equal, the comparison will fail.

A quick and reasonably elegant way to normalize the spacing is to use a tool which splits on whitespace, such as Awk.

if awk -v x=1 '$1 == "#auth" && $2 == "required" &&
               $3 == "pam_wheel.so" && $4 == "use_uid" {x=0}
            END{exit x}' /etc/pam.d/su
then
    echo "Access is not limited"
else
    echo "Access is limited"
fi

or the shell itself:

while read -r auth req so opts; do
    case $so:$opts in "pam_wheel.so:use_uid")
        test "$auth:req" == "#auth:required" &&
            echo "Access is not limited" ||
            echo "Access is limited" ;;
    esac
done </etc/pam.d/su

or a combination of the two (this would perhaps be the most elegant).

Alternatively, normalize all whitespace explicitly:

case $(tr -s '\t ' ' ' </etc/pam.d/su | grep -m 1 "pam_wheel.so use_uid") in
    '#auth required pam_wheel.so use_uid')
        echo "Access is not limited";;
    *)  echo "Access is limited";;
esac

(Notice also how this avoids the pesky temporary variable for the output.)

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

Comments

1

You could use a awk for that.

One-liner

awk '/pam_wheel.so use_uid/ { if ($0 == "#auth required pam_wheel.so use_uid") {print "yes"; } else { print "no";} } ' /etc/pam.d/su

Awk script

/pam_wheel.so use_uid/{ 
  if ($0 == "#auth required pam_wheel.so use_uid") {
    print "yes";
  } else { 
    print "no";
  }
}

Explaination

  • /pam_wheel.so use_uid/: apply following script to line containing the string _pam_wheel.so use_uid_
  • $0: contain current line processed (the one matching your pattern) and we test againt your value.
  • classic if…else structure

4 Comments

No need to be so explicit with the if/else in awk. You can do something more idiomatic like awk '/#auth required pam_wheel.so use_uid/ {print "yes"; f=1} END {if (!f) print "no"}' file.
I am still getting the output as "no". does the white spaces have anthing to do with the comparision?
yep awk don't trim lines, you can print $0 in the else to see what it contains
That is still slightly error-prone as a tab at the right place looks exactly like a single space.
0

its not the answer to your question but maybe it can help you.

            result='#auth required pam_wheel.so use_uid'    
            grep "$result" /etc/pam.d/su && echo "Access is not limited" ||echo " limited access" 

another thing with your method is that if you get more than one results in the grep your result variable will have full both results and it will not match your $result variable.

             check=$(grep -m 1"pam_wheel.so use_uid"  /etc/pam.d/su)
         result='#auth required pam_wheel.so use_uid'
            if [ "$check" =  "$result" ]; then
                echo "Access is not limited"
            else
                echo " limited access"       
            fi

and if your file has extra spaces around your text then you will have to trim the string to match. to see what your variable values are you can use

            check=$(grep -m 1"pam_wheel.so use_uid"  /etc/pam.d/su)
            result='#auth required pam_wheel.so use_uid'
            echo "D""$check""D"
            echo "D""$result""D"

here D is just any other character for you to see if your both variables have same number of spaces or not (that might be the reason for comparison fail).

Hope that helps.happy scripting :)

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.