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.

Let's assume that another user started a bunzip process, and I have a script that I'd like to start running after that bunzip finishes. What's the best way to check from inside my script that the bunzip process has finished? A call to ps with the pid specified? A pgrep bunzip? Assume that I will throw my script into a crontab that checks every 5 minutes to see if it can run. Also assume that I don't want to stop the bunzip, as it's been running for over an hour and will likely take another hour to complete.

My first reaction would be to use something like

if `ps -p 12938`
    # bunzip is done, execute the code
fi 
    # exit

But, I'm wondering if there is a better way. Also, I'm not sure how cross-unix ps -pid is.

share|improve this question
add comment

3 Answers

up vote 4 down vote accepted

Your apparent question: testing the existence of a process with a given PID

ps -p $pid is POSIX and should work on any modern non-embedded unix (not antiques or Minix or BusyBox).

A simple and portable way to test whether there is a process by a given PID is kill -0 $pid. This only works if you can send a signal to the process (signal 0 behaves like a signal that is always delivered but has no effect), meaning that kill is running under the process's effective UID or as root. If kill is running as a different user, you can test whether it signals “no such process” (ESRCH) or “operation not permitted” (EPERM), but from the shell this requires knowing how your implementation will format the error message.

Your underlying design: testing whether a process has completed

Your proposed design has a major flaw: how do you know whether that PID is the bunzip process that you were waiting for? Maybe bunzip has finished and there's now another process with its old PID. The only place where you can reliably wait on the termination of a process is in its parent.

A better approach would be to trigger on the existence of the uncompressed file and either the non-existence of the compressed file, or to check that the uncompressed file is not opened by any process (with lsof).

share|improve this answer
    
Thanks @Gilles, very good points. –  gabe. Sep 8 '11 at 14:09
add comment

There are a couple of choices.

  • Use ps and look for the PID. You need to know the processes PID though.
  • Use ps and look for bunzip, requires looking at the full command line.
  • Use lsof and see when the source file is no longer being accessed.
  • Same but check if the unzipped file is still being accessed.

None of these are truly fool proof or clean.

The easiest way is to take is out of the user's hands and write a script that performs the decompression and then runs your code.

If this is not possible, ask the user to create script that creates a pid file on disk while the file is being decompressed. You can then look for the PID file.

share|improve this answer
add comment

I see nothing wrong with using ps, but here's an alternative

if [ -e /proc/${PID} -a /proc/${PID}/exe ]
    % process active
else
    % process no longer active
fi
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.