Steven Yong Steven Yong - 1 month ago 6
Linux Question

If [ $? -ne 0 ]; not working?

I am trying to detect a running service and if not there, try to do something:

#!/bin/bash

service --status-all | grep 'My Service' &> /dev/null

if [ $? -ne 0 ]; then
echo "Service not there."
else
echo "Service is there."
fi


The service is clearly there but still I am getting "Service not there."

I read about the exit code $? I think maybe the exit code in a series of commands might have effect on what we wanna test?

So I am not sure what went wrong there?

Answer

To debug what is happening with your test, run one step at a time.

First do service --status-all by itself and check its output. Is the output what you expect it to be, and does it actually include the 'My Service' that you are grepping for?

Then run service --status-all | grep 'My Service' and check its output and exit code. Does it write out the match, and is it's exit code zero 0?

man grep tells us that:

The grep utility exits with one of the following values:

 0     One or more lines were selected.
 1     No lines were selected.
 >1    An error occurred.

and also

-q, --quiet, --silent
         Quiet mode: suppress normal output.  grep will only search a file until a
         match has been found, making searches potentially less expensive.

There are also improvements to this process that you can make...

if tests the return status of the command list that is executed, and if that status is zero the then branch is executed. Knowing this you can just test the return status of grep instead of the return status of test.

(
aside:
You are using the [ command, which is also the test command (try man test)
Tthe test command which exits with 0 when the test passes (succeeds), or with 1 when the test fails.

$ test 7 -eq 7;echo $?
0
$ test 7 -ne 7;echo $?
1
$ [ 7 -eq 2 ];echo $?
1

)

With this knowledge, again, you can directly test the exit code of grep.
Suppress grep's output with the "quiet" flag instead of redirection, and use grep -F for fixed strings, which is a.k.a. fgrep:

if ./service --status-all | fgrep -q 'My Servvice'
then
    echo "Service IS there."
else
    echo "Service NOT there."
fi
Comments