Creating shell script to mimic CRON job and execute an external file
Hi,
I wish to create a shell script which executes a PHP file ever 15 seconds. Below is my attempt, and while it "kinda" works, it needs help. First, I wish only one instance to ever be running. Currently, I can have multiple instances all running at once and updating the database causing havoc. Second, I haven't figured out how to implement stop, restart, and status, and everything causes it to start. I appreciate any help. Thanks vi /etc/init.d/15_second_cron Code:
#!/bin/bash Code:
# Make script executable |
The update appears to take more then 15 seconds and since the script is sent to the background it allows multiple instances to run. To keep things simple I would run it from rc.local and not as a service.
|
Quote:
What do you mean by rc.local versus a service? Thank you |
Your script is sending the PHP execution to the background, so right after it starts so does the sleep timer. If your PHP job ever takes more than 15 seconds, it will kick another one off before the first one ends. If you remove the "&", the sleep timer won't start until the PHP script completes.
Can you clarify what "every 15 seconds" means. Is this on the :00, :15, :30, etc.? If the script takes 5 seconds then the next iteration would only be 10 seconds after the first one completes. Or 15 seconds after the PHP script finishes you want to start the next one. For example, if it starts at 0 and runs for 5 seconds, then the next iteration would start on :20? |
Quote:
|
Depends on the distribution but rc.local is a script and actually a "service" but it is the last thing to run before x starts. Typically you add your commands to /etc/rc.local file.
You can use the time command to determine how long the script actually runs and adjust the sleep variable accordingly although without putting it in the background that should satisfy your 15 seconds apart. |
michaelk and thesnow point out the details of why your script/configuration is not working as desired.
You can't have something scheduled by cron to start every 15 minutes if it also sleeps and starts itself in 15 minutes and, most importantly, never ends. You have to do it one way or the other. It's also important, as thesnow indicates, to keep track of when things really run. You can debug this by writing to a log file somewhere with date/time stamps to see when things really happen. There are a lot of things which can influence when a process is run and how long it takes to complete. Once things work, you can disable the log if you don't need it for other things, but you might want to leave the code in for the next time things change. |
Quote:
Also, while I "could" put in in rc.local, why wouldn't I wish to create a service, and have it start upon server startup? It seems more (not that I would know) professional? Thanks! Code:
-sh-4.1$ cat /etc/rc.local |
Quote:
The part I really needed help on is how to implement start, stop, restart, and status. Right now I just have start, and if I attempt to start it twice, it will do so. Instead, if I try to start it twice, I wish to be told "this service is already running" and not to attempt to start it again. Thanks EDIT. I know this is not correct, but end result is something like this but will actually work :) Code:
#!/bin/bash |
Quote:
You might want to add some additional code to count how many times in a row the parent script woke up to find that the lock file was still there and maybe notify you that something's taking too long. That might be a way to deal with the PHP script crashed case: bail after N retries. There are a number of bells and whistles you could add to this. |
Thanks rnturn,
Is the lock file like how the apache script uses: lockfile=${LOCKFILE-/var/lock/subsys/httpd} What is this file all about? pidfile=${PIDFILE-/var/run/httpd/httpd.pid} all about? In addition to doing this, my goal is also to learn a proper and repeated approach to creating these scripts. Is there a good one to follow as a model? Thanks |
It will start at boot using rc.local. In my opinion using an init script is over kill but it can be done.
Have you actually timed your php script to see how long it runs? You want it to run every 15 secs but prevent multiple instances. Since you posted that your script is causing multiple instances that would indicate the php script is taking more then 15 seconds. Two keep this simple you can use the time command to see how long it runs and then compute the necessary sleep time interval. The problem is the while loop in your init script. Your service is the while loop which should be separate from the init script. Untested but something like: Code:
while true |
Quote:
I don't think the script will take anything close to 15 seconds, but even if it did take more, that is fine. I wish the script to start at 15 second intervals. If it takes 20 seconds, then yes, there will be two PHP processes running at the same time for 5 seconds, and this is okay. What I don't want is first starting the shell script service so the PHP runs at 15 second intervals, and then starting the shell script service again so that a who new series of 15 second intervals starts. |
The pid file contains the running process ID of the program. Typically used by the init script to see if the program is already running.
A lock file is used used to indicate that a certain resource is in use and should not be accessed by another process. Another idea would be to add the timing loop to your cron.php script. I would also make it executable and run it from /usr/bin/local. http://www.thegeekstuff.com/2012/03/lsbinit-script/ |
Quote:
There are some who pooh-pooh lock files (we occasionally get into discussions about their (dis)advantages at work) but, when you're writing scripts, they're (IMHO) the simplest way to control access to single-user-only objects. Quote:
Quote:
|
All times are GMT -5. The time now is 12:56 AM. |