1

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.

cauchi
  • 187
  • 2
  • 6
  • It seems like you need some sort of a [locking system](http://serverfault.com/questions/376717/how-to-schedule-server-jobs-more-intelligently-than-with-cron/376724#376724) – user9517 Feb 14 '13 at 13:54

3 Answers3

2

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.

Hauke Laging
  • 5,157
  • 2
  • 23
  • 40
1

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

Matt
  • 1,537
  • 8
  • 11
  • 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. – cauchi 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. – Matt Feb 18 '13 at 13:24
0

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.

John
  • 8,920
  • 1
  • 28
  • 34