Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a script that I have to run with certain frequency. This script executes a number of programs, in a loop, setting some variables in each loop. Since this script runs for hours, I run it using the linux "at" command, doint

    at now
    >> ./myscript >> output

but every once a while, I've had to kill the script. What I have done is kill the PID of the programs it executes, searching them with ps -A | grep 'name'. The issue here is that since there is a loop, I can be doing this for a long time. 10 minutes just killing processes. This is not efficient.

How can I find the PID of a script launched with "at now" a few hours -or days- ago? ps -A | grep 'bash' gives no bash process that has been running for that long.

I want to kill the script, so I don't have to kill all the process launched by the loop until it finishes, but cannot find the PID.

share|improve this question
    
It seems like you need some sort of a locking system –  Iain Feb 14 '13 at 13:54
add comment

3 Answers

up vote 1 down vote accepted

If you have pgrep and pkill available this is easier.

pgrep myscript.sh will get you the pid(s) of myscript.sh. A -o option will get you the oldest pid.

pgrep -P $myscriptPid for the pid from the above command will get you all children of your parent script.

pkill will take the same paramaters, but as the name suggests...

If pgrep is not available, a ps -ef | awk '/myscript.sh/ && !/ awk / { print $2 }' will get you the pid(s)

ps -ef | awk -v pid=$myscriptPid '{ if ( $3 == pid ) { print $2 }' would get the children of your script.

This doesn't recurse all the way down the process tree to children of children but should be sufficient

share|improve this answer
    
I got lost in your code. Simple ps -ef | grep 'output' is enough. Sorry I didn't see it before. Works better than using fuser. I just check it. –  jbcolmenares Feb 18 '13 at 12:56
    
A ps -ef | grep myscript can also return the pid of the grep process rather than what you are looking for leading to ps -ef | grep mysscript | grep -v grep | awk '{ print $2; }'. The above is equivalent but removes extra calls to grep from the pipeline as awk can do it all. –  mtm Feb 18 '13 at 13:24
add comment

fuser shows you the PID of the process(es) which have opened the file output.

The more elegant solution is using cgroups, though. You could use systemd for that. Just create a service file for your script and start it with

systemctl start myscript.service

If you need to kill it

systemctl stop myscript.service

kills the script and all processes it has created.

I do not understand what use at now has. If you just want to detach the process from the terminal then use nohup or screen. Giving the screen session a name would make killing the script easy, too.

share|improve this answer
add comment

The script process should show up with the name "myscript". Alternately, you can find one of the programs it executes, and trace the PPIDs back up as far as you need to.

share|improve this answer
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.