linux – Why Does Variable Assigned ZERO Have Value TWO?

linuxshellshell-script

I am trying to create a script that populates a variable with zero when a process called 'enigma2' does not exist.

When I run this script…

#!/bin/sh
ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep|wc -l | awk '{print $1}')
echo $ENIGMA_PID
echo "$ENIGMA_PID"

I get the output…

0  
0  

Which is what I expect.

But when I run this script:

#!/bin/sh

# Check if the no_enigma file exists
if [ -f /home/root/no_enigma ]; then
    # If enigma2 is running then kill it
    ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep|wc -l | awk '{print $1}')
    echo $ENIGMA_PID
    echo "$ENIGMA_PID"

    re='^[0-9]+([.][0-9]+)?$'
    if ! [[ $ENIGMA_PID =~ $re ]] ; then
       echo "error: Not a number" >&2; exit 1
    else
        echo "It IS a number"
    fi

        if [ "$ENIGMA_PID" -gt 0 ]; then
            echo $ENIGMA_PID
            echo "$ENIGMA_PID"
            echo "enigma2 is running"
            killall enigma2
        else
            echo "enigma2 is not running"       
        fi
    # Check if minisatip is running already, if not then start it
    MINI_PID=$(ps ax|grep minisatip|grep -v grep|wc -l | awk '{print $1}')
        if [ "$MINI_PID" -gt 0 ]; then
            echo "minisatip is already running"
        else
            echo "minisatip is not running"
            echo "starting minisatip"
            /usr/bin/minisatip --satip-xml http://127.0.0.1:8554 -R /usr/share/minisatip/html       
        fi
else
    # The no_enigma file does not exist
    # Check if minisatip is running, if yes then kill it
    MINI_PID=$(ps ax|grep minisatip|grep -v grep|wc -l | awk '{print $1}')
        if [ "$MINI_PID" -gt 0 ]; then
            echo "minisatip is running, killing it now"
            killall minisatip
        else
            echo "minisatip is not running"
        fi  
    # Check if enigma2 is running already, if not then start it
    ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep|wc -l | awk '{print $1}')
        if [ "$ENIGMA_PID" -gt 0 ]; then
            echo "enigma2 is already running"
        else
            echo "enigma2 is not running"
            echo "starting enigma2"
            /home/root/run_enigma.sh            
        fi
fi

I get this output…

2  
2  
It IS a number  
2  
2  
enigma2 is running  
killall: enigma2: no process killed  
minisatip is already running 

If I remove #!/bin/sh from the top of the second script I get the expected output..

0  
0  
It IS a number  
enigma2 is not running  
minisatip is already running  

Why do these three lines:

#!/bin/sh
ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep|wc -l | awk '{print $1}')
echo $ENIGMA_PID
echo "$ENIGMA_PID"

Correctly report the $ENIGMA_PID variable as having value 0
But in the second script those same three lines report the $ENIGMA_PID variable as having value 2?

Update

Here are answers to questions in the comments below..

This screenshot shows me running both scripts. Each time the minisatip process was running and the enigma2 process was not running.

enter image description here

The path of the first script, the one with just 3 or 4 lines, is /home/root/test.sh and I can run it from anywhere, it seems, simply like this # test.sh
The path of the second script is /usr/bin/enigma2.sh and as you can see I run it simply like enigma2.sh

As suggested I updated both scripts to remove the wc and awk from the piped command whose output is meant to assign a value to the variable: ENIGMA_PID

I changed /home/root/test.sh to this:

#!/bin/sh
ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep)
echo $ENIGMA_PID
echo "$ENIGMA_PID"

And in /usr/bin/enigma2.sh I added these lines to the top of the script…

#!/bin/sh
ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep)
echo $ENIGMA_PID
echo "$ENIGMA_PID"

# Check if the no_enigma file exists
...
....

Now I ran the scripts and this screenshot shows the output..

enter image description here

The process I am checking for is a binary with path: /usr/bin/enigma2. This binary is not running. Yet, when the enigma2.sh script runs there are two process ids. Is this because the script itself is called enigma2? Well then why are their two process ids called enigma2 and not one?

Question
What do I need to change in this command
ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep|wc -l | awk '{print $1}')

… when it's in a script called /usr/bin/enigma2.sh
… so it doesn't count the script, it is a part of, as a running process?
… the result should be ZERO if the binary /usr/bin/enigma2 is not running.

Thank you!

Flex

Best Answer

It is clear from you edit that the second script is called enigma2.sh, and that you call it by writing enigma2.sh on the command line. The script is somewhere in your path (you declare that it is at /usr/bin/enigma2.sh, and I shall assume that /usr/bin is in your PATH variable). Combining that the script could be found (in the PATH) by the shell and that the first line of the script is #!/bin/sh, the kernel will start a new process that has a command line of:

/bin/sh enigma2.sh

You can confirm this by simply making the first lines of that script as this:

#!/bin/sh 
ps ax|grep enigma2
exit 0
...

You don't need to erase the script, just place the lines shown above at the start of the script and leave all the rest below.

Run it to get:

$ enigma2.sh
 3109 pts/6    S+     0:00 /bin/sh enigma2.sh
 3111 pts/6    S+     0:00 grep enigma2

There are two processes that include the word enigma2.

That explains part of the problem. Now, if you change the script to:

#!/bin/sh 
enigma_pid=$(ps ax|grep enigma2)
echo "$enigma_pid"
exit 0
...                     # leave the old script below (no need to erase it).

And run it:

$ enigma2.sh
 3509 pts/6    S+     0:00 /bin/sh ./enigma2.sh
 3510 pts/6    S+     0:00 /bin/sh ./enigma2.sh
 3512 pts/6    S+     0:00 grep enigma2

When you use a $(…) one additional process appear.

Removing the grep process with grep -v grep leaves 2 processes.

That is the number you get 2.

Note: Please, don't use uppercase variable names, those are reserved for environment variables.
Don't use ENIGMA_PID

Solutions

  • First: If you are going to identify a process by its name, don't use the exact same name in other programs or scripts. You may call the script enigma33.sh.

  • Second: In this case, you can restrict grep to match a name that ends at 2. The script ends in .sh and won't be counted. Use

     grep '[e]nigma2$'
    

And, since all you need is the count of matching lines use (-c):

enigma_pid=$(ps ax | grep -c '[e]nigma2$')

Yes, no need for grep -v grep since the regex [e]nigma2$ can not be equal (as an string) to enigma2.

Edited script:

#!/bin/sh


# Detect If enigma2 is running.
enigma_pid=$(ps ax|grep -c '[e]nigma2$')
echo "$enigma_pid"    

# Deetct if minisatip is running.
mini_pid=$(ps ax|grep -c '[m]inisatip$' )


# Check if the no_enigma file exists
if [ -f /home/root/no_enigma ]; then
    if [ -z "${enigma_pid##*[!0-9]*}" ] ; then
       echo "error: Not a number" >&2; exit 1
    else
        echo "It IS a number"
    fi
    
    if [ "$enigma_pid" -gt 0 ]; then
        echo "$enigma_pid"
        echo "enigma2 is running"
        killall -r '[e]nigma2$'           # make killing more restrictive
    else
        echo "enigma2 is not running"
    fi
    # Check if minisatip is running already, if not then start it
    if [ "$mini_pid" -gt 0 ]; then
        echo "minisatip is already running"
    else
        echo "minisatip is not running"
        echo "starting minisatip"
        /usr/bin/minisatip --satip-xml http://127.0.0.1:8554 -R /usr/share/minisatip/html       
    fi
else    
    # The no_enigma file does not exist
    # Check if minisatip is running, if yes then kill it
    if [ "$mini_pid" -gt 0 ]; then
        echo "minisatip is running, killing it now"
        killall minisatip
    else
        echo "minisatip is not running"
    fi  
    # Check if enigma2 is running already, if not then start it
    if [ "$enigma_pid" -gt 0 ]; then
        echo "enigma2 is already running"
    else
        echo "enigma2 is not running"
        echo "starting enigma2"
        /home/root/run_enigma.sh            
    fi
fi
Related Question