- How to test if a process is running with grep in bash?
- 3 Answers 3
- 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.
How to test if a process is running with grep in bash?
Which outputs a large string including the port of the proccesses involved in my_application. If my_application is not running it outputs:
3873 pts/0 S+ 0:00 grep my_application
I need a condition to test the output of ps ax | grep my_application and do exit 2 in case my_application is still running. Any ideas?
if the output of ps ax | grep my_application command produces two or more lines as output then it means that the process is currently running or otherwise it’s not.
3 Answers 3
You can add brackets to exclude the grep process:
ps ax | grep -q '[m]y_application' && exit 2
If my_application is running, ps ax will print my_application along with the grep command and pattern. Grep understands [m] as a character class, but it will not match the litteral string ‘[m]’ printed by ps ax , so the grep process is excluded.
@tripleee, maybe I should rephrase the comment: To improve the quality of your answer, it’s best if you explain how the solution works, rather than just putting the solution. While links to the manual are also appreciated, an excerpt where the relevant part is highlighted helps the OP a lot.
@Shahbaz This question and this answer are both extremely frequently repeated. I was unable to quickly find a precise duplicate on Stack Overflow but brief googling should get you everything you need.
@tripleee, brief googling would answer 99% percent of the questions on SO. This topic actually comes up a lot (a recent discussion) and the answer has always been to answer these trivial questions, rather than close it, refer them to google, etc. If you wish to argue about this, please refer to the posts in meta (I’m just following the policy of SO).
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».