16

I am trying to automatically check if a process is running or not and have to perform next steps accordingly. I had written a bash script but it doesn't seem to work.

if ps aux | grep [M]yProcessName > /dev/null
then
  echo "Running"
else
  echo "Not running"
fi

Is my if statement wrongly used?

11
  • Your if looks fine. Why don't you run it and find out yourself? It took me a minute to copy the if into a file and start it. Commented Nov 6, 2012 at 23:21
  • I did run it and its not working, that's why I asked Commented Nov 6, 2012 at 23:22
  • How is it "not working? What do you get when you remove the output redirection? Commented Nov 6, 2012 at 23:24
  • 1
    @noMAD because it is actually designed for exactly that, and doesn't spawn an additional subshell. Commented Nov 6, 2012 at 23:41
  • 6
    For future reference, posting a question with a meaningless "its not working" statement and no information about what "its not working" means makes it a very poor question that will probably cost you rep. Commented Nov 7, 2012 at 0:05

10 Answers 10

12

You don't want to know if a particular process (of known pid) is running (this can be done by testing if /proc/1234/ exists for pid 1234) but if some process is running a given command (or a given executable).

Notice that the kill(2) syscall can be portably used to check if a given process is running (with a 0 signal, e.g. kill(pid,0)). From inside a program, this is a common way to check that a process of known pid is still existing and running (or waiting).

You could use the pidof command to find the processes running some executable, e.g. pidof zsh to find all the zsh processes. You could also use killall -s 0 zsh

And you might be interested by the pgrep utility and the /proc filesystem.

Sign up to request clarification or add additional context in comments.

Comments

8
ps aux | grep [M]yProcessName | grep -v grep

3 Comments

can you pls explain why 3 greps are required?
The grep -v grep filters out the line(s) that contain "grep". This is necessary because ps aux | grep foo will capture lines listing all the processes currently running that contain the string "foo", which includes the command itself! In other words, you will always have a line in your results, whether a foo process is running or not. Using grep -v grep, you will have 0 lines when no foo process is running, and you will only get the line(s) pertaining to actual foo processes, not your command.
This answer is wrong and should probably be removed. The [M] already takes care of filtering out the grep process, a second grep is NOT needed in this case. Pattern [M]yProcessName only matches string MyProcessName, whereas grep shows up as grep [M]yProcessName in the process list, thus it does not match and does not get included.
2

Using -z to check if a string is empty or not, something like this could work:

line=$(ps aux | grep [M]yProcessName)
if [ -z "$line" ]
then
    echo "Not Running"
else
    echo $line > /dev/null
    echo "Rinnung"
fi

1 Comment

His first implementation is better. grep returns non-zero when it doesn't match, so test is not needed. The [] around the M eliminates the need for the grep -v grep.
2

There is a solution:

if [ "$(ps aux | grep "what you need" | awk '{print $11}')" == "grep" ]; then ... elif [ ... ]; then ... else ... fi

This works fine in Debian 6. '{print $11}' is needed, because the sytem treats grep as a process as well

1 Comment

-1 This is horribly botched newbie code and inefficient to boot. It does not solve the OP's problem (which was unclear in the first place) and offers no additional functionality over the original, more elegant and correct code.
2
processid =$(ps aux | grep 'ProcessName' | grep -v grep| awk '{print $2}')

The above command will give you the process id. Assign that process id to a variable and do this -->

if cat /proc/$processid/status | grep "State:  R (running)" > /dev/null
then
  echo "Running"
else
  echo "Not running"
fi

2 Comments

too late to revert my +1: there is is a problem in grepping for state "R (running)" because often what you think of as a running process will be in state "sleeping" when it is idle.
Ya. But the Question was to check if the process running or not. One can extend the above code for his convenience. It was just to give a lead.
2

Just to explicitly mention a way this answer alluded to, pgrep is the best way to do this by process name:

pgrep [M]yProcessName

If a process whose name matches "[M]yProcessName" is running, pgrep will print its PID to stdout and will exit with code 0. Otherwise, it will print nothing and exit with code 1.

Comments

1
SMBD=$(pidof smbd)
if [ "$SMBD" == "" ];
then
   /etc/init.d/samba start;
else
   /etc/init.d/samba restart;
fi

Comments

1

return 0 means success while others failed

kill -0 `pid`; echo $?

Comments

0

On my system, ps aux | grep ProcessName always get a line of that grep process like:

edw4rd     9653  0.0  0.0   4388   832 pts/1    S+   21:09   0:00 grep --color=auto ProcessName

So, the exit status is always 0. Maybe that's why your script doesn't work.

1 Comment

That's why the OP's grep uses a regex which doesn't match itself.
-1

try this

ps aux | grep [M]yProcessName | grep -v grep

2 Comments

Writing [M]y instead of My here makes the grep -v grep unnecessary, because [M]y does not match itself.
Thanks @Zack :-) I will start using it this way :-) I also thinking that those [] around M were useless. Awesome workaround it is :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.