cron: run a process but only if it isnt running?

the simplest way, use pgrep

in crontab:

* * * * * pgrep processname > /dev/null || /path/to/processname -args0 -args1

Run a script, instead of directly the program. There are many possibilities. For example :

MYPROG="myprog"
RESTART="myprog params"
PGREP="/usr/bin/pgrep"
# find myprog pid
$PGREP ${MYPROG}
# if not running
if [ $? -ne 0 ]
then
   $RESTART
fi

This script will not run again if the previous instance hasn't finished. If you want to not run something if another specific process is running, see harrymc's script.

DATE=`date +%c`;
ME=`basename "$0"`;
LCK="./${ME}.LCK";
exec 8>$LCK;

if flock -n -x 8; then
  echo ""
  echo "Starting your script..."
  echo ""

[PUT YOUR STUFF HERE]

  echo ""
  echo "Script started  $DATE";
  echo "Script finished `date +%c`";
else
  echo "Script NOT started - previous one still running at $DATE";
fi

You could use a lock file in your script, but please see Process Management.

flock is one utility that can be used.


This is usually handled by the program itself rather than by cron. There are two standard techniques for this:

1) grep the output of ps to see whether there's a process by that name already running

2) On startup, first check for the existence of a pid (process id) file, usually at /var/run/program_name.pid, and, if it exists, read the pid out of the file and check whether that process still exists; if it does, refuse to start. If the pid file doesn't exist or the pid in the file has gone away, then create a pid file, write your process id into it, and continue on with normal startup.

While it's technically possible to write bash pipes that will do either of these directly into your crontab, it's better to add them to the program being started (so that they'll apply no matter how it gets started) or to write a wrapper script to handle this, as harrymc suggested.