I am trying to replace the crontab using a new crontab stored at /tmp/crontab.txt.
$output = '';
$output .= "Existing Crontab contents:<br>";
$output .= shell_exec('crontab -l');
$output .= "<br>new contents:<br>";
$output .= file_get_contents('/tmp/crontab.txt');
$output .= "<br>Result of import:<br>";
$output .= shell_exec('crontab /tmp/crontab.txt');
$output .= shell_exec('crontab -l');
echo $output;
The output is:
Existing Crontab contents:
1 2 3 4 5 existing
new contents:
* * * * * echo 'test'
Result of import:
1 2 3 4 5 existing
You can see the import does not work and does not show an error.
Apache is running as 'nobody'. I have tried crontab -u nobody /tmp/crontab.txt as root and it works.
Is this a permissions issue? If so, why is php (running as nobody) unable to update it's own cron? How do I get around this?
Thanks
Try changing your import line to this:
$output .= shell_exec('crontab /tmp/crontab.txt 2>&1');
that'll redirect stderr to stdout and let PHP catch any error message cron's spitting out.
Related
I'm moving from a webserver with CPanel to one with Plesk. Under Cpanel, it's fairly simple to create and remove cronjobs with php:
<?php
// Create cron
$new_cron = "30 * * * * cd /home/account/public_html/; /usr/local/bin/php -f controller.php ".$argument1.PHP_EOL;
$output = shell_exec('crontab -l');
file_put_contents('/tmp/crontab.txt', $output.$new_cron);
exec('crontab /tmp/crontab.txt');
// Remove cron
$cronjob = "30 * * * * cd /home/account/public_html/; /usr/local/bin/php -f controller.php ".$argument1.PHP_EOL;
$output = shell_exec('crontab -l'); // pull current cron jobs
if (strstr($output, $cronjob)) // found
{
$newcron = str_replace($cronjob,"",$output); // delete it
file_put_contents('../tmp/crontab.txt', $newcron.PHP_EOL); // Save
exec('crontab ../tmp/crontab.txt'); // Send back
}
?>
Under Plesk I have scheduled tasks. How do I use PHP to create and remove those? Or is there another method?
You can schedule task at Home > Subscriptions > example.tld > Scheduled Tasks:
Since Plesk 12.5 there are options of task type:
I've found at this forum that it is possible to edit crontab like this:
a. crontab -l > $tmpfile
b. edit $tmpfile
c. crontab $tmpfile
d. rm $tmpfile
So, I'm trying to implement this solution on php:
include('Net/SSH2.php');
$ssh = new Net_SSH2('myhost');
if (!$ssh->login('user', 'password'))
{
echo'Login Failed';
}
$ssh->exec('crontab -l > /var/www/tmp.txt');
$content=file_get_contents("/var/www/tmp.txt");
$content.='0 0 1 * * /usr/bin/php /var/www/clearPreviousMonth1.php';
$file=fopen("/var/www/tmp.txt", "w");
fputs($file,$content);
fclose($file);
$ssh->exec('crontab /var/www/tmp.txt');
echo $content;
I can see edited content of crontab in my browser and tmp file, but when I use crontab -e it's not changed. What's my mistake?
I had to add new string before the end of file. In other case it's not added to crontab.
changed $content.='0 0 1 * * /usr/bin/php /var/www/clearPreviousMonth1.php';
to $content.="0 0 1 * * /usr/bin/php /var/www/clearPreviousMonth1.php\n";
note that it's neccessary to use " instead of ', because it just will append \n symbols to last string
Basically I have developed a small script that adds a cron job into a file called "crontask" and then I want to execute it so then it becomes a cron job. Here is the script:
<?php
$filename = "../../tmp/crontask.txt";
$output = shell_exec('crontab -l');
$something = file_put_contents($filename, $output.'* * * * * NEW_CRON'.PHP_EOL);
$cngDir = chdir('../../tmp/');
echo exec('crontab ' . getcwd() . '/crontask.txt');
//var_dump($exe);
?>
Everything is ok, the path is the same and if I copy and paste the path that prints out IT will carry out the cronjob but in PHP it won't???
Everything works, apart from the exec function, it doesn't execute it. Any ideas?
In terminal, if I do:
string(25) "crontab /tmp/crontask.txt"
it will execute it.
Try the following things:
Call to the command using the full command path. Sometimes $PATH is not set in the script environment and can't find the command if not.
Setup the working dir of the script using http://php.net/manual/en/function.chdir.php
Use the absolute path to access to the file
I've had a similar issue with cron jobs
I looked at your code and got a couple of ideas.
I used absolute paths
Here is my code:
$myFile = "/home/user/tmp/crontab.txt";
$addcron = "
0 0 * * * cronjob1 " . PHP_EOL .
"0 18 * * 1-5 conjob2 " . PHP_EOL .
"0 9 * * * cronjob3 " . PHP_EOL ;
$output = exec('crontab -l > ' . $myFile );
file_put_contents($myFile,$addcron ,FILE_APPEND);
echo exec('crontab ' . $myFile );
echo "<h3>Cron job successfully added!</h3>";enter code here
basically i wrote the list of previous cronjobs to a file and then appended the file with new cronjobs. Then added the new list of cronjobs with the crontab command.
the linux write to file command ' > ' was what did the trick ;)
cron line look's like:
*/1 * * * * /usr/bin/php /path/to/CRON.php > /path/to/log/CRON_LOG.txt 2> /dev/null
CRON.php
<?php
require_once 'config.php';
define('CRON', dirname(dirname(__FILE__)));
$parts = explode("/",__FILE__);
$ThisFile = $parts[count($parts) - 1];
chdir(substr(__FILE__,0,(strlen(__FILE__) - strlen($ThisFile))));
unset($parts);
unset($ThisFile);
$CRON_OUTPUT = "STARTING CRON # ".date("m-d-Y H:i:s")."\r\n";
$CRON_OUTPUT .= CleanLog() . "\r\n";
$CRON_OUTPUT .= "\r\n";
echo $CRON_OUTPUT;
$fh = fopen(''.CRON.'/log/CRON_LOG.txt', 'a');
fwrite($fh, $CRON_OUTPUT);
fclose($fh);
die();
?>
CleanLog function:
global $db;
$resp = '';
$db->query('SQL');
$resp = 'Deleted '.$db->rows_affected.' entries from table';
return $resp;
In file only these two lines showing and function by the time as i can see executed two times:
CRON_LOG.txt
STARTING CRON # 02-26-2012 21:26:01
Deleted 0 entries from table
STARTING CRON # 02-26-2012 21:26:01
Deleted 0 entries from table
What's wrong with it, why it only produce those lines and file doesn't updated (in file only date/time changing, nothing more, it should add more lines and even file size should grow up) ?
You should be using >> for redirection to append to the file, rather than > which overwrites the log each time the script runs.
*/1 * * * * /usr/bin/php /path/to/CRON.php >> /path/to/log/CRON_LOG.txt 2> /dev/null
##---------------------------------------^^^^^^
There really isn't any need to do fopen()/fwrite() inside the script itself, since the cron job is already handling the output redirection.
Is there anyway to get the exit status code for a php script run in the background via exec($cmd, $output, $exitCode)?
For example:
exec('php script.php &', $output, $exitCode);
If the trailing '&' isn't included then $exitCode works as expected, it's always 0 otherwise.
For anybody that finds themselves here, my solution was to make a php script that takes a script as an argument. The new script is called to the background and handles exit statuses appropriately.
For example:
$cmd = 'php asynchronous_script.php -p 1';
exec("php script_executor.php -c'$cmd' &");
The second script looks something like
$opts = getOpt('c:');
$cmd = rtrim($opts['c'], '&');
$exitCode = 0;
$output = '';
exec($cmd, $output, $exitCode);
if ($exitCode > 0) {
...
}
I found something that is probably quite equivalent to Pradeep's solution. Someone posted about this on the function's documentation page.
http://www.php.net/manual/en/function.exec.php#101506