Bash script to check running process

Bash

Bash Problem Overview


I wrote a bash-script to check if a process is running. It doesn't work since the ps command always returns exit code 1. When I run the ps command from the command-line, the $? is correctly set, but within the script it is always 1. Any idea?

#!/bin/bash
SERVICE=$1

ps -a | grep -v grep | grep $1 > /dev/null
result=$?
echo "exit code: ${result}"
if [ "${result}" -eq "0" ] ; then
    echo "`date`: $SERVICE service running, everything is fine"
else
    echo "`date`: $SERVICE is not running"
fi

Bash version: GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)

Bash Solutions


Solution 1 - Bash

There are a few really simple methods:

pgrep procname && echo Running 
pgrep procname || echo Not running 
killall -q -0 procname && echo Running 
pidof procname && echo Running

Solution 2 - Bash

I tried your version on BASH version 3.2.29, worked fine. However, you could do something like the above suggested, an example here:

#!/bin/sh

SERVICE="$1"
RESULT=`ps -ef | grep $1 | grep -v 'grep' | grep -v $0`
result=$(echo $ps_out | grep "$1")

if [[ "$result" != "" ]];then
    echo "Running"
else
    echo "Not Running"
fi

Solution 3 - Bash

This trick works for me. Hope this could help you. Let's save the followings as checkRunningProcess.sh

#!/bin/bash
ps_out=`ps -ef | grep $1 | grep -v 'grep' | grep -v $0`
result=$(echo $ps_out | grep "$1")
if [[ "$result" != "" ]];then
    echo "Running"
else
    echo "Not Running"
fi

Make the checkRunningProcess.sh executable.And then use it.
Example to use.

20:10 $ checkRunningProcess.sh proxy.py
Running
20:12 $ checkRunningProcess.sh abcdef
Not Running

Solution 4 - Bash

I use this one to check every 10 seconds process is running and start if not and allows multiple arguments:

#!/bin/sh

PROCESS="$1"
PROCANDARGS=$*

while :
do
	RESULT=`pgrep ${PROCESS}`

	if [ "${RESULT:-null}" = null ]; then
			echo "${PROCESS} not running, starting "$PROCANDARGS
			$PROCANDARGS &
	else
			echo "running"
	fi
	sleep 10
done	

Solution 5 - Bash

Check if your scripts name doesn't contain $SERVICE. If it does, it will be shown in ps results, causing script to always think that service is running. You can grep it against current filename like this:

#!/bin/sh
SERVICE=$1
if ps ax | grep -v grep | grep -v $0 | grep $SERVICE > /dev/null
then
    echo "$SERVICE service running, everything is fine"
else
    echo "$SERVICE is not running"
fi

Solution 6 - Bash

Working one.

!/bin/bash
CHECK=$0
SERVICE=$1
DATE=!/bin/bash
CHECK=$0
SERVICE=$1
DATE=date
OUTPUT=$(ps aux | grep -v grep | grep -v $CHECK |grep $1)
echo $OUTPUT
if [ "${#OUTPUT}" -gt 0 ] ;
then echo "$DATE: $SERVICE service running, everything is fine"
else echo "$DATE: $SERVICE is not running"
fi

OUTPUT=$(ps aux | grep -v grep | grep -v $CHECK |grep $1)
echo $OUTPUT
if [ "${#OUTPUT}" -gt 0 ] ;
then echo "$DATE: $SERVICE service running, everything is fine"
else echo "$DATE: $SERVICE is not running"
fi

Solution 7 - Bash

Despite some success with the /dev/null approach in bash. When I pushed the solution to cron it failed. Checking the size of a returned command worked perfectly though. The ampersrand allows bash to exit.

#!/bin/bash
SERVICE=/path/to/my/service
result=$(ps ax|grep -v grep|grep $SERVICE)
echo ${#result}
if  ${#result}> 0 
then
        echo " Working!"
else
		echo "Not Working.....Restarting"
    	/usr/bin/xvfb-run -a /opt/python27/bin/python2.7 SERVICE &
fi

Solution 8 - Bash

#!/bin/bash
ps axho comm| grep $1 > /dev/null
result=$?
echo "exit code: ${result}"
if [ "${result}" -eq "0" ] ; then
echo "#!/bin/bash
ps axho comm| grep $1 > /dev/null
result=$?
echo "exit code: ${result}"
if [ "${result}" -eq "0" ] ; then
echo "date: $SERVICE service running, everything is fine"
else
echo "date: $SERVICE is not running"
/etc/init.d/$1 restart
fi
: $SERVICE service running, everything is fine"
else
echo "#!/bin/bash
ps axho comm| grep $1 > /dev/null
result=$?
echo "exit code: ${result}"
if [ "${result}" -eq "0" ] ; then
echo "#!/bin/bash
ps axho comm| grep $1 > /dev/null
result=$?
echo "exit code: ${result}"
if [ "${result}" -eq "0" ] ; then
echo "date: $SERVICE service running, everything is fine"
else
echo "date: $SERVICE is not running"
/etc/init.d/$1 restart
fi
: $SERVICE service running, everything is fine"
else
echo "date: $SERVICE is not running"
/etc/init.d/$1 restart
fi
: $SERVICE is not running"
/etc/init.d/$1 restart
fi
Something like this

Solution 9 - Bash

Those are helpful hints. I just needed to know if a service was running when I started the script, so I could leave the service in the same state when I left. I ended up using this:

   HTTPDSERVICE=$(ps -A | grep httpd | head -1)

   [ -z "$HTTPDSERVICE" ] &&  echo "No apache service running." 

Solution 10 - Bash

I found the problem. ps -ae instead ps -a works.

I guess it has to do with my rights in the shared hosting environment. There's apparently a difference between executing "ps -a" from the command line and executing it from within a bash-script.

Solution 11 - Bash

A simple script version of one of Andor's above suggestions:

!/bin/bash

pgrep $1 && echo Running

If the above script is called test.sh then, in order to test, type: test.sh NameOfProcessToCheck

e.g. test.sh php

Solution 12 - Bash

I was wondering if it would be a good idea to have progressive attempts at a process, so you pass this func a process name func_terminate_process "firefox" and it tires things more nicely first, then moves on to kill.

# -- NICE: try to use killall to stop process(s)
killall ${1} > /dev/null 2>&1 ;sleep 10

# -- if we do not see the process, just end the function
pgrep ${1} > /dev/null 2>&1 || return

# -- UGLY: Step trough every pid and use kill -9 on them individually
for PID in $(pidof ${1}) ;do

	echo "Terminating Process: [${1}], PID [${PID}]" 
	kill -9 ${PID} ;sleep 10

	# -- NASTY: If kill -9 fails, try SIGTERM on PID
	if ps -p ${PID} > /dev/null ;then
		echo "${PID} is still running, forcefully terminating with SIGTERM"
		kill -SIGTERM ${PID}  ;sleep 10
	fi

done

# -- If after all that, we still see the process, report that to the screen.
pgrep ${1} > /dev/null 2>&1 && echo "Error, unable to terminate all or any of [${1}]" || echo "Terminate process [${1}] : SUCCESSFUL"

Solution 13 - Bash

I need to do this from time to time and end up hacking the command line until it works.

For example, here I want to see if I have any SSH connections, (the 8th column returned by "ps" is the running "path-to-procname" and is filtered by "awk":

ps | awk -e '{ print $8 }' | grep ssh | sed -e 's/.*\///g'

Then I put it in a shell-script, ("eval"-ing the command line inside of backticks), like this:

#!/bin/bash

VNC_STRING=`ps | awk -e '{ print $8 }' | grep vnc | sed -e 's/.*\///g'`

if [ ! -z "$VNC_STRING" ]; then
    echo "The VNC STRING is not empty, therefore your process is running."
fi

The "sed" part trims the path to the exact token and might not be necessary for your needs.

Here's my example I used to get your answer. I wrote it to automatically create 2 SSH tunnels and launch a VNC client for each.

I run it from my Cygwin shell to do admin to my backend from my windows workstation, so I can jump to UNIX/LINUX-land with one command, (this also assumes the client rsa keys have already been "ssh-copy-id"-ed and are known to the remote host).

It's idempotent in that each proc/command only fires when their $VAR eval's to an empty string.

It appends " | wc -l" to store the number of running procs that match, (i.e., number of lines found), instead of proc-name for each $VAR to suit my needs. I keep the "echo" statements so I can re-run and diagnose the state of both connections.

#!/bin/bash

SSH_COUNT=`eval ps | awk -e '{ print $8 }' | grep ssh | sed -e 's/.*\///g' | wc -l`
VNC_COUNT=`eval ps | awk -e '{ print $8 }' | grep vnc | sed -e 's/.*\///g' | wc -l`

if  [ $SSH_COUNT = "2" ]; then
    echo "There are already 2 SSH tunnels."
elif  [ $SSH_COUNT = "1" ]; then
    echo "There is only 1 SSH tunnel."
elif [ $SSH_COUNT = "0" ]; then
    echo "connecting 2 SSH tunnels."
    ssh -L 5901:localhost:5901 -f -l USER1 HOST1 sleep 10;
    ssh -L 5904:localhost:5904 -f -l USER2 HOST2 sleep 10;
fi

if  [ $VNC_COUNT = "2" ]; then
    echo "There are already 2 VNC sessions."
elif  [ $VNC_COUNT = "1" ]; then
    echo "There is only 1 VNC session."
elif [ $VNC_COUNT = "0" ]; then
    echo "launching 2 vnc sessions."
    vncviewer.exe localhost:1 &
    vncviewer.exe localhost:4 &
fi

This is very perl-like to me and possibly more unix utils than true shell scripting. I know there are lots of "MAGIC" numbers and cheezy hard-coded values but it works, (I think I'm also in poor taste for using so much UPPERCASE too). Flexibility can be added with some cmd-line args to make this more versatile but I wanted to share what worked for me. Please improve and share. Cheers.

Solution 14 - Bash

A solution with service and awk that takes in a comma-delimited list of service names.

First it's probably a good bet you'll need root privileges to do what you want. If you don't need to check then you can remove that part.

#!/usr/bin/env bash

# First parameter is a comma-delimited string of service names i.e. service1,service2,service3
SERVICES=$1

ALL_SERVICES_STARTED=true

if [ $EUID -ne 0 ]; then
  if [ "$(id -u)" != "0" ]; then
    echo "root privileges are required" 1>&2
    exit 1
  fi
  exit 1
fi

for service in ${SERVICES//,/ }
do
    STATUS=$(service ${service} status | awk '{print $2}')

    if [ "${STATUS}" != "started" ]; then
        echo "${service} not started"
        ALL_SERVICES_STARTED=false
    fi
done

if ${ALL_SERVICES_STARTED} ; then
    echo "All services started"
    exit 0
else
    echo "Check Failed"
    exit 1
fi

Solution 15 - Bash

The most simple check by process name :

 bash -c 'checkproc ssh.exe ; while  [ $? -eq 0  ] ; do  echo "proc running";sleep 10; checkproc ssh.exe; done'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionelasticsecurityView Question on Stackoverflow
Solution 1 - BashAndorView Answer on Stackoverflow
Solution 2 - BashAndersView Answer on Stackoverflow
Solution 3 - BashandroidyueView Answer on Stackoverflow
Solution 4 - Bashuser2128898View Answer on Stackoverflow
Solution 5 - BashsudaView Answer on Stackoverflow
Solution 6 - BashDani RadulescuView Answer on Stackoverflow
Solution 7 - BashAndrew Scott EvansView Answer on Stackoverflow
Solution 8 - BashMike VeltmanView Answer on Stackoverflow
Solution 9 - BashMikeView Answer on Stackoverflow
Solution 10 - BashelasticsecurityView Answer on Stackoverflow
Solution 11 - BashCMPView Answer on Stackoverflow
Solution 12 - BashMike QView Answer on Stackoverflow
Solution 13 - BashRalph RotondoView Answer on Stackoverflow
Solution 14 - BashTomSchoberView Answer on Stackoverflow
Solution 15 - BashArtemView Answer on Stackoverflow