Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

How can I determine if a process is running or not and then have a bash script execute some stuff based on that condition...

For example:

  • if process 'abc' is running, do this

  • if it is not running , do this.

share|improve this question
    
Feel it important to note that none of the solutions below take into account the state of the process. A comment on one of my questions brought me here, but an answer on it clued me into different state's of a program, like zombie process' (Not what I would describe as a "running" process). A full list of what the STAT column values, in the output of ps, indicates is here for those inclined to write an answer that accommodates this, or edit their own. –  user66001 Oct 19 '13 at 17:54
    
Related discussion: unix.stackexchange.com/questions/74185/… –  b.long Jun 17 at 17:08
add comment

6 Answers 6

up vote 20 down vote accepted
+50

A bash script to do something like that would look something like this:

#!/bin/bash

# Check if gedit is running
if ps aux | grep "[g]edit" > /dev/null
then
    echo "Running"
else
    echo "Stopped"
fi

This script is just checking to see if the program "gedit" is running.

The square brackets are useful to avoid the output of the grep command. Without this the conditional will always return true, because the grep command start a process with the same content of the searched string.

share|improve this answer
    
Exactly what I was going to do, you beat me to it! any reason why you chose aux instead of -e? –  jackweirdy Jun 29 '12 at 22:09
    
No reason. It was just the first thing that came to my head. Old habits die hard. –  John Vrbanac Jun 29 '12 at 22:11
1  
is it necessary for the 1st letter to be in square brackets? like "[g]edit"?? or "[c]onky"?? –  Nirmik Jun 29 '12 at 22:13
3  
Yeah, the brackets around first letter of the program name is to eliminate false positives. Because you are running grep to look for the program name, you have to exclude grep from counting itself from the running processes list. Does that make sense? –  John Vrbanac Jun 29 '12 at 22:18
1  
@JohnVrbanac: why would grep find itself in the process list if you're not searching for "grep"? –  endolith Nov 30 '12 at 2:57
show 7 more comments

This is what I use:

#!/bin/bash

#check if abc is running
if pgrep abc >/dev/null 2>&1
  then
     # abc is running
  else
     # abc is not running
fi

In plain English: if 'pgrep' returns 0, the process is running, otherwise it is not.


Related reading:

Bash Scripting :: String Comparisons

Ubuntu Manuals pgrep

share|improve this answer
    
thanx! i tried this too n it works perfectly too :) –  Nirmik Jun 29 '12 at 23:10
    
pgrep has the same 15 character limit "feature" previously mentioned, thus for example pgrep gnome-power-manager would also fail –  Thorsen Jul 2 '12 at 16:04
    
Make sure you use pgrep's -x option: "Only match processes whose name (or command line if -f is specified) exactly match the pattern." –  Alastair Irvine Jul 21 at 4:31
add comment

Any solution that uses something like ps aux | grep abc or pgrep abc are flawed.

Why?

Because you are not checking if a specific process is running, you are checking if there are any processes running that happens to match abc. Any user can easily create and run an executable named abc (or that contains abc somewhere in its name or arguments), causing a false positive for your test. There are various options you can apply to ps, grep and pgrep to narrow the search, but you still won't get a reliable test.

So how do I reliably test for a certain running process?

That depends on what you need the test for.

I want to ensure that service abc is running, and if not, start it

This is what init and upstart are for. They'll start the service and ensure its pid gets stored in a pidfile. Try to start the service again (via init or upstart) and it will check the pidfile, and either start it if it's not there, or abort if it's already running. This is still not 100% reliable, but it's as close as you get.

See How can I check to see if my game server is still running... for other solutions.

abc is my script. I need to make sure only one instance of my script is running.

In this case, use a lockfile or a lockdir. E.g.

#!/usr/bin/env bash

if ! mkdir /tmp/abc.lock; then
    printf "Failed to aquire lock.\n" >&2
    exit 1
fi
trap 'rm -rf /tmp/abc.lock' EXIT  # remove the lockdir on exit

# rest of script ...

See Bash FAQ 45 for other ways of locking.

share|improve this answer
1  
While this is technically true, I've ne er personally encountered such a problem in real life. Most programs don't change their names in ways that break scripts. Thus, for simple scripts something like pgrep or ps is perfectly adequate and your approach seems like overkill. If you're writing a scrip for public distribution, though, you should write it in the safest way possible. –  Scott Severance Jun 30 '12 at 13:21
    
@ScottSeverance Programs changing names is not the issue; that would require intervention regardless. It's other users running the same program, or other programs with similar names that will suddenly cause the script to get false positives and thus do the wrong thing. I just prefer "works" rather than "mostly works". –  geirha Jun 30 '12 at 14:15
    
I misspoke. But many of us run single-user systems. And in a multiple user situation, it's easy to also grep for the username. –  Scott Severance Jun 30 '12 at 21:03
add comment

First thing that came to my mind for your problem:
ps aux | grep -i abc will show the details of the process if its running. You may match the number of lines or time for which its running and compare with zero or any other manipulation. When you run the above command it will show you atleast one line of output i.e. detail about the process created by thi grep command.. So take care of that.
That should do as a simple hack. Put it in the bash script and see if its helpful.

share|improve this answer
add comment

I usually have a 'pidof -x $(basename $0)' on my scripts to check if it's already running.

share|improve this answer
add comment

Riffing on @rommel-cid's idea, you can use pidof with the || (||) to run a command if the process does not exist and && to run something if the process does exist, thus creating a quick if/then/else conditional. For example here's one with a running process (my chrome browser, whose process name is "chrome") and one testing for a process that does not exist. I suppressed the standard output using 1>/dev/null so that it doesn't print:

$ (pidof chrome 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run instea\
d"
its running? ok, so am i then
$ (pidof nosuchprocess 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run\
 instead"
it's not running? ok i'll run instead
$
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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