- Linux/Unix command to determine if process is running?
- 15 Answers 15
- You SHOULD know the PID !
- How to determine if process is running (by pid)
- How to determine whether a process is running or not and make use it to make a conditional shell script?
- 13 Answers 13
- Why?
- So how do I reliably test for a certain running process?
- I want to ensure that service abc is running, and if not, start it
- abc is my script. I need to make sure only one instance of my script is running.
Linux/Unix command to determine if process is running?
I need a platform independent (Linux/Unix|OSX) shell/bash command that will determine if a specific process is running. e.g. mysqld , httpd . What is the simplest way/command to do this?
15 Answers 15
While pidof and pgrep are great tools for determining what’s running, they are both, unfortunately, unavailable on some operating systems. A definite fail safe would be to use the following: ps cax | grep command
The output on Gentoo Linux:
14484 ? S 0:00 apache2 14667 ? S 0:00 apache2 19620 ? Sl 0:00 apache2 21132 ? Ss 0:04 apache2
The output on OS X:
42582 ?? Z 0:00.00 (smbclient) 46529 ?? Z 0:00.00 (smbclient) 46539 ?? Z 0:00.00 (smbclient) 46547 ?? Z 0:00.00 (smbclient) 46586 ?? Z 0:00.00 (smbclient) 46594 ?? Z 0:00.00 (smbclient)
On both Linux and OS X, grep returns an exit code so it’s easy to check if the process was found or not:
#!/bin/bash ps cax | grep httpd > /dev/null if [ $? -eq 0 ]; then echo "Process is running." else echo "Process is not running." fi
Furthermore, if you would like the list of PIDs, you could easily grep for those as well:
ps cax | grep httpd | grep -o '^[ ]*2*'
Whose output is the same on Linux and OS X:
The output of the following is an empty string, making this approach safe for processes that are not running:
echo ps cax | grep aasdfasdf | grep -o '^[ ]*1*'
This approach is suitable for writing a simple empty string test, then even iterating through the discovered PIDs.
#!/bin/bash PROCESS=$1 PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*3*'` if [ -z "$PIDS" ]; then echo "Process not running." 1>&2 exit 1 else for PID in $PIDS; do echo $PID done fi
You can test it by saving it to a file (named «running») with execute permissions (chmod +x running) and executing it with a parameter: ./running «httpd»
#!/bin/bash ps cax | grep httpd if [ $? -eq 0 ]; then echo "Process is running." else echo "Process is not running." fi
Please keep in mind that you’re simply parsing the output of ps ax which means that, as seen in the Linux output, it is not simply matching on processes, but also the arguments passed to that program. I highly recommend being as specific as possible when using this method (e.g. ./running «mysql» will also match ‘mysqld’ processes). I highly recommend using which to check against a full path where possible.
The process can be running, but stopped. So if the goal is to test if mysqld or httpd are «up and running» (responding), you should also check if it is stopped or not.
Sorry, but while the answer is certainly right from a semantic point of view I’m fully against trying to find a process by pattern matching on the process arg vector. Any such approach is doomed to fail sooner or later (you actually admit to that yourself, by saying that more checks are needed). I’ve added my own recommendation in a separate answer.
grep will also find itself running (e.g. ps cax | grep randomname will always return 0 because grep finds grep randomname (hope this is clear. ). One fix is to add square brackets around the first letter of the process name, e.g. ps cax | grep [r]andomname .
ps cax may not output command name wholly. E.g it prints «chromium-browse» instead of «chromium-browser».
You SHOULD know the PID !
Finding a process by trying to do some kind of pattern recognition on the process arguments (like pgrep «mysqld» ) is a strategy that is doomed to fail sooner or later. What if you have two mysqld running? Forget that approach. You MAY get it right temporarily and it MAY work for a year or two but then something happens that you haven’t thought about.
Only the process id (pid) is truly unique.
Always store the pid when you launch something in the background. In Bash this can be done with the $! Bash variable. You will save yourself SO much trouble by doing so.
How to determine if process is running (by pid)
So now the question becomes how to know if a pid is running.
This is POSIX and hence portable. It will return the pid itself if the process is running or return nothing if the process is not running. Strictly speaking the command will return a single column, the pid , but since we’ve given that an empty title header (the stuff immediately preceding the equals sign) and this is the only column requested then the ps command will not use header at all. Which is what we want because it makes parsing easier.
This will work on Linux, BSD, Solaris, etc.
Another strategy would be to test on the exit value from the above ps command. It should be zero if the process is running and non-zero if it isn’t. The POSIX spec says that ps must exit >0 if an error has occurred but it is unclear to me what constitutes ‘an error’. Therefore I’m not personally using that strategy although I’m pretty sure it will work as well on all Unix/Linux platforms.
How to determine whether a process is running or not and make use it to make a conditional shell script?
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.
13 Answers 13
A bash script to do something like that would look something like this:
#!/bin/bash # Check if gedit is running # -x flag only match processes whose name (or command line if -f is # specified) exactly match the pattern. if pgrep -x "gedit" > /dev/null then echo "Running" else echo "Stopped" fi
This script is just checking to see if the program «gedit» is running.
Or you can only check if the program is not running like this:
if ! pgrep -x "gedit" > /dev/null then echo "Stopped" fi
@DreadPirateShawn can you tell me why use /dev/null and not simply a 0? Using the number makes the code way more readable, at least for a noob (such as me). No redirect, no nothing
@Silviu huh? Googling /dev/null : «/dev/null redirects the command standard output to the null device, which is a special device which discards the information written to it» . using 0 would redirect the command output to a file called 0 . In this case, I’d advise becoming more comfortable with > /dev/null — you’ll see it everywhere, as it’s the standard / proper way to discard output.
Woot thanks, I used this for a nice little script that checks if a program is running before it executes. (although I had to extend it a little since google chrome’s executable doesn’t have the same name as it’s run command, the exec name is just chrome.)
Please add the -x parameter to pgrep so that it is looking for the exact application or else it will get a false correct if it finds the same string inside the name of another app. I just spent 1 hour to find that out.
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 systemd is for. It can start the service automatically and keep track of it, and it can react when it dies.
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 acquire 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.
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.
@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».
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.
@jp093121 The EXIT trap is triggered when the script exits. Whether it exits because it reaches end of script, an exit command, or receives a signal (that can be handled), the rm command is run. So as long as it ends after the trap has been set, the lock should be gone.
#!/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:
pgrep has the same 15 character limit «feature» previously mentioned, thus for example pgrep gnome-power-manager would also fail
Make sure you use pgrep’s -x option: «Only match processes whose name (or command line if -f is specified) exactly match the pattern.»
This answer suffers false positives due to passing improper options to pgrep . Moreover, this assumes pgrep to be installed in the first place. See also this authoritative answer.
I usually have a pidof -x $(basename $0) on my scripts to check if it’s already running.
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 $
## bash ## function to check if a process is alive and running: _isRunning() < ps -o comm= -C "$1" 2>/dev/null | grep -x "$1" >/dev/null 2>&1 > ## example 1: checking if "gedit" is running if _isRunning gedit; then echo "gedit is running" else echo "gedit is not running" fi ## example 2: start lxpanel if it is not there if ! _isRunning lxpanel; then lxpanel & fi ## or _isRunning lxpanel || (lxpanel &)
Note: pgrep -x lxpanel or pidof lxpanel still reports that lxpanel is running even when it is defunct (zombie); so to get alive-and-running process, we need to use ps and grep
Substantially superior to any other answers listed here, despite receiving not a single upvote. So, why is this the ideal specimen? Let us enumerate the reasons why: (A) it’s shell-agnostic (despite specifying bash ), (B) it’s distro-agnostic (because it only leverages ps and grep ), (C) it’s resilient against false positives (because it passes -o and -C to ps and -x to grep ), and (D) it’s resilient against zombie processes (as noted). In short, it’s the CLI equivalent of spring-fed glacier water imported at considerable expense from the fjords of Norway.
pgrep -u [user] -x [name] >/dev/null
«-x» means «exact match».