Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tail | grep -q always returning true

Tags:

shell

When I execute this code, the loop always ends at first time (even when the last two lines of auth.log doen't contain "exit"), which means that $c always gets some string:

while true;
do
    c=$(tail -2 /var/log/auth.log | grep -q "exit")
    if $c ;
    then
            echo "true"
            unset c
            break
    fi

done

Do you know why c=$(tail -2 /var/log/auth.log | grep -q "exit") is always getting some kind of string? I think it is becaues of tail.

I can use the -o option and then compare strings, but I prefer to use a boolean inside the if condition.

like image 796
hakimoto Avatar asked Oct 18 '22 13:10

hakimoto


1 Answers

grep -q by design returns no output, it simply signals via its exit code whether a match was found.

Thus, you can simply use your pipeline directly as a condition:

while true;
do
    if tail -2 /var/log/auth.log | grep -q "exit";
    then
            echo "true"
            break
    fi
done

As for what you tried:

As Benjamin W. implies in a comment on the question, executing a command expanding to the empty string is always considered a successful command.

Note: Whether the command is effectively empty because the variable in question is unset or, as in this case, was explicitly assigned a null (empty) string, doesn't matter.

Thus, given that $c is invariably empty - because grep -q by design never returns stdout output - the if condition always evaluates to true.

To be clear: $c, since it is not being used in a conditional (if $c; ... rather than if [ "$c" ]; ...), is interpreted as a command to execute rather than as a string to test for emptiness.

If the command whose output is captured in $c were to generate stdout output, you'd have to test for that with a conditional: if [ -n "$c" ]; then ... (or, more succinctly, if [ "$c" ]; then ...).

like image 110
mklement0 Avatar answered Nov 15 '22 10:11

mklement0