Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

My script accepts a process name as an input and kills it, I tried using pgrep but its returning two PIDs , one for the process which is running and one for the script which accepts the process name as input so am stuck! I tried using the pgrep -fo option too but that did not help either. Any suggestions would be helpful this is my script

#!/bin/bash
ProcessName=$1

pID= pgrep -fl $ProcessName

echo $pID

so when i invoke the script its returning two PIDs

bash-3.00$ ./dynamic_values.sh test-Process

10534 /xxx/xxo/xxx/xxe --run --propFile /application/test/test-Process_Archive.tra --innerProcess
23401 /bin/bash ./dynamic_values.sh test-Process

I was expecting just 10534 but it picked up the script too . Version of OS just incase

bash-3.00$ uname -a
Linux xxxxxx 2.6.9-67.0.1.
share|improve this question
    
Why write a script for this? Lots of tools have already been written for these kind of jobs, you just need to find the right one. Based on your question, I would suggest you try pkill. It uses the same process findng logic as pgrep so you already know how to use it to find your process, but rather than returning the PID's to you, it just goes ahead and sends them a kill signal for you. In the mean time, it also takes care of details such as not killing itself. –  Caleb Aug 29 '12 at 10:20
    
pkill when using -f (which he is doing) will have the same problem. –  bahamat Aug 29 '12 at 15:30
    
@bahamat: Really? So do you have to use -x in combination with -f to make sure you are matching the whole thing? I'm surprised pkill doesn't have a built in way to handle this. –  Caleb Aug 29 '12 at 16:24
    
@Caleb From what I've experienced, on OS X and Solaris it does the right thing, but Linux uses a different implementation. I had to get real targeted with my regexp to get what I wanted on Linux (I was writing a script that would kill old instances of itself). –  bahamat Aug 29 '12 at 16:28
    
I have never had pkill kill itself before killing the processes I wanted to kill, so I'd always assumed the implementation was good. –  jw013 Aug 29 '12 at 18:40
show 1 more comment

4 Answers

up vote 2 down vote accepted

I had to tackle this same problem a couple of weeks ago. pgrep and pkill support extended regular expressions so it's a simple matter of getting the right regexp.

This is your script with the regexp that I used.

#!/bin/bash
ProcessName=$1

pID= pgrep -fl "^(/.*)?${ProcessName}\s"

echo $pID

Although using pkill (as Caleb suggested) is better.

pkill -fl "^(/.*)?${ProcessName}\s"

You may still need to tweak the regexp to get the desired results for your use case and how the program is being executed.

Now, if there are actually multiple processes running with that name they will of course be killed. If you want to avoid that you can use -o to kill only the oldest matching process or -n to kill only the newest. If you want only one, but neither the oldest or newest then you probably shouldn't be using p(kill|grep).

share|improve this answer
    
bahamat , thank you for the tip and I was able to use regex successfully. –  greenhorn Aug 30 '12 at 4:53
add comment

if you exclude the #!/bin/bash then it will not fork another process for the script but you will lose the choice of what shell it runs with. bash is default enough though and those that are smiler should be able to run this.

not sure if that will get rid of the second process ID though.

I understand this is not complete but it is late and I have to work in the am but this "should" work as a quick fix.

share|improve this answer
    
thanks for taking time this late in the evening , unfortunately it returns an empty string as well as the correct pid,like this bash-3.00$ ./dynamic_values.sh test-Process 10534 /opt/XXengine --run --propFile /opt/application/test/test-Process_Archive.tra --innerProcess $ –  greenhorn Aug 29 '12 at 3:58
add comment

Wouldn't using

| grep -v $$

to exclude your process from the list help?

share|improve this answer
    
The point of pgrep and pkill is that you don't have to pipe it to grep. –  bahamat Aug 29 '12 at 15:38
add comment
#!/bin/bash

ProcessName=$1

pID=`pgrep -fl $ProcessName`

echo "$pID" | grep -v  "^$$"
share|improve this answer
    
The point of pgrep and pkill is that you don't have to pipe it to grep. –  bahamat Aug 29 '12 at 15:38
    
it depends. in this case we should filter out current process by it's pid –  hostmaster Aug 29 '12 at 20:15
    
No, you don't understand. The one and only point of pgrep is to not pipe to grep. If you're going to use grep you might as well use ps | grep. –  bahamat Aug 29 '12 at 20:34
    
I am afraid you have misunderstanding here. main point of prep look up processes based on name and other attributes –  hostmaster Aug 30 '12 at 6:58
    
Years ago during the Solaris start up every init script called the equivalent of kill $(ps -ef | grep somedaemon | grep -v grep | awk '{print $2}'). The extra forks were increasing the boot up time by launching 5x the number of processes necessary. pkill and pgrep were written so you could just call pkill somedaemon and significantly reduce boot up times. –  bahamat Aug 30 '12 at 18:01
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.