1

I'm building a script in bash for use on Linux (SLES 11SP3). I'd like to check whether a certain process exists by looking up it's pid using this syntax:

pid="$(ps -ef | grep -v grep | grep /sbin/syslog-ng | awk '{print $2}')" 

This fills variable pid with the pid of the syslog-ng process. Then I want to use this variable in an if statement:

if [ ${pid} > 0 ]; then do something else do something else fi 

The problem is that this if statement seems to always be false, even if the variable pid has a value higher than 0. So, the else part is always executed instead of the correct (if condition is true) statement.

I had a similar issue with the use of wc -l to check the existence of filesystems:

exist_tmp=$(df -x fuse.gvfs-fuse-daemon -h | grep /tmp | wc -l) if [ ${exist_tmp} > 0 ]; then do something fi 

This would not work, even if the variable has a value of 1, indicating the existence of a /tmp filesystem. It started working (or at least doing what I wanted it to do), when I changed the syntax to this:

if [ ${exist_tmp} != 0 ]; then do something fi 

The difference between greater than 0 and not equal to 0 eludes me a bit in this used case.

The questions therefor are:

  1. Does anybody have an idea why the pid lookup and if statement won't do what I want it to do?
  2. Does anybody have an idea what the problem with the > 0 and != 0 might have been?

Any input is greatly appreciated!

3
  • Try -gt instead of > the former compares integers, the latter strings. Commented May 30, 2015 at 9:11
  • pgrep can help you to reduce your script Commented May 30, 2015 at 9:19
  • [ is a command. > is a redirection. cmd argument > 0 redirects the output of cmd to a file named 0.. So does [ ${exist_tmp} > 0 ] Commented May 31, 2015 at 1:31

4 Answers 4

3

With bash, comparisons like <, >, != are for comparing strings lexicographically. To compare their integer values, you do > like this:

if [ "$a" -gt "$b" ] 

and inequality like this:

if [ "$a" -ne "$b" ] 

See this reference for more detail or other comparators.

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

2 Comments

So, anything coming from "wc -l" or a grep of a process ID should be compared with the "-gt" and "-ne" type operators? The ones I used are for string comparison.
That's right. To clarify, all bash values are strings — but if your string contains only digits and you want to compare its integer value, you should use -gt, -ne, etc.
0

ps -ef | grep -v grep | grep /sbin/syslog-ng | awk '{print $2}' can evaluate to multiple lines. You need to pick one of them. To pick the first one, append head -n 1:

... | awk '{print $2}' | head -n 1 

The second example works because wc -l always returns one number on a single line.

1 Comment

I've noticed a strange thing: while pid=$(ps -ef | grep -v grep | grep /sbin/syslog-ng | awk '{print $2}') will work from the command prompt (if I echo $pid it will give me a number), it will return an empty variable when used in the script (saw this when I traced the part where this variable is filled). Any thoughts?
0

If you want to compare integers, better use arithmetic if statement:

if (( pid > 0 )); then do something else do something else fi 

Comments

0

A simpler way to get process PIDs is to use pgrep.

pid=$(pgrep -fo /sbin/syslog-ng) # oldest pid=$(pgrep -fn /sbin/syslog-ng) # newest pids=($(pgrep -f /sbin/syslog-ng)) # an array of pids 

If there might be more than one process running you should use -o or -n to select the oldest or newest process, respectively. Or you could change your script to save and work with all the PIDs.

Then to compare numbers you should either use -gt and -lt with square brackets, or switch to ((...)) which is designed for arithmetic comparisons.

if ((pid > 0)) # great if [[ $pid -gt 0 ]] # good if [ "$pid" -gt 0 ] # meh 

If you went with the array approach then you would loop over all the PIDs.

for pid in "${pids[@]}"; do ... done 

In fact, if your goal is simply to test for a process's existence, you can skip getting the PID and test pgrep's exit code.

if pgrep -f /sbin/syslog-ng > /dev/null; then # process exists fi 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.