3

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

4
  • 4
    What is the name of the first script? May 21 '20 at 0:18
  • 2
    How do you run the two scripts ? Writing ./scriptname on the cli? Then: what are the actual names (and paths) of each scriptname ?
    – ImHere
    May 21 '20 at 0:23
  • 1
    ... as to why it's 2 rather than 1, it's likely because the shell forks for the command substitution - see for example Command substitution. Spawned process name is identical to the parent one May 21 '20 at 12:43
  • 1
    You're using bash syntax (the [[ ... =~ ... ]]) but trying to declare it as a sh script. Don't do that. Change the first line to #!/bin/bash and don't run it with sh.
    – roaima
    May 21 '20 at 22:43
5

As explained ps ax command does produce a different result when ran from your second script.

You just need to debug your second script to figure out why that command is producing a different value, to do so (and just for a debugging purpose) replace

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

With

ENIGMA_PID=$(ps ax|grep enigma2|grep -v grep)
echo $ENIGMA_PID
echo "$ENIGMA_PID"

And check what's really different on the output and what's causing the issue... then adapt your script accordingly. Also as suggested by the comments if your script name contains enigma2 that will be detected as false positive.

2
  • I added an update to my question in response to your comments. Yes, the problem seems to be the name of the script is the same as the name of the process I am checking for. But I'd like to keep that ps ax... command in a script called enigma2.sh Can the command be modified to ignore any process names that refer to the script in which that command is run? May 21 '20 at 21:43
  • 1
    Ok I did some more googling and I changed the ps ax... command to: ps ax|grep -w "/usr/bin/enigma2$"|grep -v grep and now the grep only matches if it finds a process called: /usr/bin/enigma2. The command gives a result of 1 when that binary IS running and 0 when the binary is NOT running... even when the command is in a script called: enigma2.sh This is what I wanted. Thank you. May 21 '20 at 22:08
5

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.