How to start/stop a cronjob using PHP?
If I type crontab -l
in the command-line I can see the following line:
# * * * * * /usr/bin/php /home/user/ever开发者_如何学编程y_minute_script.php
To start this cronjob, I need to edit the file using crontab -e
command, remove the comment character at the beginning of the line, save the edited file, and exit the editor.
To stop this cronjob, the same steps, but adding the comment character at the beginning of the line.
I want to achieve exactly the same effect using a PHP script, instead of manually editing the file.
I did some research and found in a forum, the following message:
Call "crontab -e" with the EDITOR environment variable set to a php script. That script can modify the file and when it exits crontab will re-read the file and update.
So, I have tried something, and it worked. I will paste the working code below:
#!/usr/bin/php
<?php
$on = "* * * * * /usr/bin/php /home/user/every_minute_script.php\n";
$off = "# * * * * * /usr/bin/php /home/user/every_minute_script.php\n";
$param = isset( $argv[1] ) ? $argv[1] : '';
$filename = isset( $argv[2] ) ? $argv[2] : '';
if ( $param == 'activate' )
{
shell_exec( 'export EDITOR="/home/user/cron.php on"; crontab -e' );
}
elseif( $param == 'deactivate' )
{
shell_exec( 'export EDITOR="/home/user/cron.php off"; crontab -e' );
}
elseif( in_array( $param, array( 'on', 'off' ) ) )
{
if ( !is_writable( $filename ) )
exit();
$crontab = file( $filename );
$key = array_search( $param == 'on' ? $off : $on, $crontab );
if ( $key === false )
exit();
$crontab[$key] = $param == 'on' ? $on : $off;
sleep( 1 );
file_put_contents( $filename, implode( '', $crontab ) );
}
exit();
?>
As it is, we have a single script named cron.php
located at /home/user
folder, set to be executable (chmod a+x cron.php
) and called from the command-line (PHP-CLI). Later I will tweak it to run from the web, which is my intent.
Usage: ./cron.php activate
to enable the cronjob and ./cron.php deactivate
to disable it.
The script sets the EDITOR environment variable properly (to itself) and then calls crontab -e
, which on its turn calls the EDITOR (which is now the same cron.php script) passing the temporary crontab file location as an argument. Then, the proper crontab line is found and changed, and the modified version is saved, substituting the temporary file. When the script exits, crontab will update.
This does exactly what I wanted, and fit my needs.
The other answers are nice and may fit different needs and scenarios, and I want to thank everybody who contributed.
Rather than messing programatically with crontab (which is subtle and quick to anger), I'd suggest making a check inside your every_minute_script.php:
if (!file_exists('/your/path/run_every_minute_script')) {
exit;
}
This way, the script will still start every minute, but if the condition isn't met (/your/path/run_every_minute_script
doesn't exist), it will terminate immediately without further processing.
(Of course, you can substitute different conditions there, e.g. checking the database for permission etc.)
If you need the output mailed, you can use a wrapper script. Crontab:
* * * * * /your/path/wrapper.sh > /dev/null 2> /dev/null
The wrapper script then runs the job proper, collects its output and errors, and if those aren't empty, mails them out (note that you could also make the check inside the wrapper script; we didn't, as it relied on database).
Here's a pretty cool tutorial for creating exactly this kind of functionality with PHP.
Put your stop/start condition at the start of every_minute_script.php
if($condition == false) {
exit();
}
Could you place some kind of logic at the beginning of every_minute_script.php
that checks a flag to see if it should do anything? That way it could spin up and then just quickly stop if there is no work to do.
Or is that too inefficient for your purposes?
精彩评论