set cron job from php - php

I try To set cron job from php but every time i try the code blow it's not work.
tell me what is the problem with this code
$cron = $this->generator();
file_put_contents("cron.txt", $cron);
shell_exec('crontab cron.txt');
generator function make cron job string like below
12 1 * * * /usr/bin/sample >/dev/null 2>&1
the cron.txt file is fine. it contain the string but shell_exec some how not working

Running your scrip with the hardcoded $corn locally works fine for me, i've included a couple of lines to clear the crontab in the beginning and couple of line to confirm the entry. see bellow.
$cron = '12 1 * * * /usr/bin/sample >/dev/null 2>&1';
file_put_contents('cron.txt', $cron);
shell_exec('crontab -r');
shell_exec('crontab cron.txt');
// To check the result
$output = [];
exec('crontab -l',$output);
print_r($output);
Output:
Array
(
[0] => 12 1 * * * /usr/bin/sample >/dev/null 2>&1
)
And here is a way to check the result of the crontab cron.txt execution:
$output = $return = [];
exec('crontab cron.txt',$output, $return);
var_dump($output, $return);
There will be no output nor return in case of success:
array(0) {
}
int(0)

after many search in Dr Google i found out the answer
i have to change the use to Apache user which is www-data
so the command change to crontab -u www-data cron.txt

The issue is that the apache server will run as a separate limited resource account that rightfully should not create cron jobs. This is a pretty easy way to get the host server compromised. Especially if this is running in a publicly accessible ip address space.
However, if the environment is secure and your server administrator allows, you can have the apache process either run as a higher privileged account (yours for example) or to use the suexec feature to run as a designated account with limited but appropriate permissions.

Related

SSH and exec() users differ

I have a Lightsail instance in AWS, and it's a LAMP stack. Previously, I (or bitnami, not sure) created a cron for SSL. It looks something like this:
0 0 * * * sudo /opt/bitnami/letsencrypt/lego --path /o...
If I connect via SSH and run crontab -l, I get the following output (the second cron is for test purposes):
0 0 * * * sudo /opt/bitnami/letsencrypt/lego --path /o...
* * * * * sudo /usr/bin/touch /opt/bitnami/apache2/htdocs/.htaccess
Now, I'm thinking about adding more cron jobs that are related to the app. Adding cron jobs manually (via SSH) is tedious. I want to be able to do this in the UI. I'm saying this because I've seen this done (e.g. in DirectAdmin, Plesk Panel, WHMCS, etc.)
So I started searching for ways to view/edit/delete cron jobs in the PHP. The idea seems simple. Get the current cron jobs (crontabs -l), parse and modify them, and load it back (crontabs file). So I tried to get the current cron jobs (in a PHP file, from the browser), but failed:
exec("crontab -l", $crons);
exec("crontab -u bitnami -l", $crons_bitnami);
exec("sudo crontab -l", $sudo_crons);
exec("sudo crontab -u bitnami -l", $sudo_crons_bitnami);
var_dump(exec("whoami")); // daemon
var_dump(shell_exec("crontab -l")); // NULL
var_dump($crons); // array(0) { }
var_dump($crons_bitnami); // array(0) { }
var_dump($sudo_crons); // array(0) { }
var_dump($sudo_crons_bitnami); // array(0) { }
I get empty results. I get the two cron jobs that I added if I run crontabs -l in the SSH, but this doesn't work in the PHP. So I checked the users. If I type whoami in SSH, I get bitnami. In PHP, it returns daemon. I searched more and figured out that each user has its own cron jobs. In SSH, I'm the user bitnami and it has two cron jobs. Why am I daemon in PHP? Is that the reason I'm getting an empty result? If so, can/how do I change it?
I tested the same code on other servers, and I seem to get correct results. The user is not daemon and I can see the cron jobs. So this might be Lightsail/bitnami related. Nevertheless, is there anything that I can do to fix it?

Crontab not running

I've been having some issues with crontab recently. After switching servers, I realized none of my cronjobs are being run. After looking at PHP info, I realized php was run with CGI, so I realized I had to switch lynx -dump URL_HERE to php -q PATH_HERE.
In the actual PHP file, I stared it out like #!/usr/bin/php -q to define where php is located on my server. However, it's not getting run. I've even set up crontab to send me an email once anything runs. No email. I've checked my junk, trash, spam, and I've even tried switching emails. Nothing.
Here's what I have now: * * * * * php -q /home/USER/public_html/file.php.
If I copy & paste it into the command line, it works wonderfully. If I run it through crontab, it doesn't get run.
You are missing envrionment variables. Try a simple test like this
add this to your crontab
* * * * * set > /tmp/vars
wait 2 -3 minutes, go back and remove the crontab entry you just created.
Next,
From the shell command line you normally use
set > myvars
diff myvars /tmp/vars
This will show you the differEnce in envIrionment. Modify your cron job environment. Just add what is needed.
You can do a couple things in order to debug this.
1) In your crontab change your entry to:
* * * * * php -q /home/USER/public_html/file.php > /tmp/filecron 2>&1
Make sure you edit the entry by typing:
crontab -e
Then run:
tail -f /tmp/filecron
To debug the output as it runs.
2) As sudo user or root, tail the cron log to make sure your cron is executing properly:
sudo tail -f /var/log/cron
The first step will give you information related to the php file itself (syntax errors etc) if that is what is failing. The second step will help you out if the crontab itself is not configured properly.
You are intending this job to run every 5 minutes right ? This is what it will do with your stated line.

How to run crontab-e?

I am currently reading this documentation here where I want to use CRON. Now it says in the first section that I need to enter in a command: crontab -e.
Do I only need to enter this in a simple text editor file and just upload the file into the server?
I am using helios.hud.ac.uk so would this be the correct command:
* * 25 10 * helios.hud.ac.uk/u00000000/Mobile/inactivatesession.php
This will execute this php script below (inactivatesession.php):
<?php
include('connect.php');
$createDate = mktime(0,0,0,10,25,date("Y"));
$selectedDate = date('d-m-Y', ($createDate));
$sql = "UPDATE Session SET Active = ? WHERE DATE_FORMAT(SessionDate,'%Y-%m-%d' ) <= ?";
$update = $mysqli->prepare($sql);
$update->bind_param("is", 0, $selectedDate);
$update->execute();
?>
The url for this php script is: helios.hud.ac.uk/u00000000/Mobile/inactivatesession.php
I havn't used CRON before so just need little help on it.
Thanks
If you are making a crontab that will access a remote webpage (which is what this is as it is not on your local server) you need to prepend the URL with wget
* * 25 10 * wget -O - http://helios.hud.ac.uk/u00000000/Mobile/inactivatesession.php
It will run the script on the server and output it to standard output (which in most servers will be emailed to you)
This assumes that you have a linux machine. crontab -e sets up a cron tab for your user account. So you can't really upload a crontab, but if you have cpanel or similar, most times you have access to cron from there.
You open a shell (probably through SSH) to your server
You run the command crontab -e
You edit the crontab according to your needs (if you want to run a php script over http you need to use wget)
You save and exit If you didn't make any mistakes, you will get a message that crontab was updated

Why is crontab not executing my PHP script?

I have built one php file to check some result, so that I need to setup a cronjob.
I set one to run every 30 minute, so that the results will be send. However, I don't know why my crontab did not run after every 30 minute.
Here is how I set the crontab:
*/30 * * * * php /var/www/html/result.php
I have confirmed my file directory is correct. What I not sure is about the timing part: isn't it possible to use */30 * * * * or 30 * * * * ? I set */30 * * * * and did not work.
Given
*/30 * * * * php /var/www/html/result.php
There are multiple possibilities why it is not working:
First of all it is important to check if the simple execution of php /var/www/html/result.php. This is required. But unfortunately, accomplishing this does not mean that the problem is solved.
The path of the php binary has to be added.
*/30 * * * * php /var/www/html/result.php
to be changed to
*/30 * * * * /usr/bin/php /var/www/html/result.php
or whatever coming from which php.
Check the permission of the script to the user running the crontab.
Give execution permission to the file: chmod +x file. And make sure the crontab is launched by a user having rights to execute the script. Also check if the user can access the directory in which the file is located.
To be safer, you can also add the php path in the top of the script, such as:
#!/usr/bin/php -q
<?php
...
?>
Make sure the user has rights to use crontab. Check if he is in the /etc/cron.d/deny file. Also, make a basic test to see if it is a crontanb or php problem.
* * * * * touch /tmp/hello
Output the result of the script to a log file, as William Niu suggested.
*/30 * * * * /usr/bin/php /var/www/html/result.php > /tmp/result
Use the -f option to execute the script:
*/30 * * * * /usr/bin/php -f /var/www/html/result.php > /tmp/result
Make sure the format in crontab is correct. You can do so for example using the site Crontab.guru.
To sum up, there are many possible reasons. One of them should solve the problem.
It may be because php is not in the path. crontab has a very minimal path. So, include the full path for your php program.
you can test your cron commands by piping the output to a file, e.g.
*/30 * * * * php /var/www/html/result.php > /tmp/result.log
From this reference page, under "Crontab Environment":
cron invokes the command from the user’s HOME directory with the
shell, (/usr/bin/sh). cron supplies a default environment for every
shell, defining:
HOME=user’s-home-directory
LOGNAME=user’s-login-id
PATH=/usr/bin:/usr/sbin:.
SHELL=/usr/bin/sh
Also, /30 syntax might not be supported by all platforms, so, try to change it to 0,30 instead.
Had a similar issue; from command line, it worked, but from cron, no go.
had a "include ("./connect.php"); in my php code for the db stuff.
Removed that, and added the connect.php code directly into the php script, and it worked from cron.
I had a similar issue on Ubuntu 14.04.1 and the problem turned out to be the way I was modifying the crontab:
I was using sudo crontab -e instead of just crontab -e and this caused my changes to be ignored.
I had a funny one regarding this. Although my scripts would run manually, they wouldn't run from crontab.
Turns out that because the script was being run from /usr/bin/php rather that the location of the file (as it does when I run it manually) my php require wasn't finding the files I wanted. Changing that to reflect the full address fixed it.
troubleshooting by running the script as /usr/bin/php -f /var/www/myfile.php helped me find the issue
You can use */30 * * * * wget http://my.domain.com/path/to/php/result.php
But Crontab executes the task using the current user that ran crontab -e. When you use wget it’s handled by Apache using the www-data user/group pair
First, make sure the script works as expected.
$ php /var/www/html/result.php
Second, edit the crontab for the Apache user account
$ sudo crontab -u www-data -e
or
$ sudo crontab -u root -e
Now add the crontab and output to a log file.
*/30 * * * * php /var/www/html/result.php > /tmp/result.log
After a day of puzzling why my script would work directly (to send data in an email to a gmail account) I discovered that all the deliberate sends worked when I clicked the url and all the cron sends went into spam. No idea why but I thought I'd share it.
Willem's answer showed me the way. In my case, I have a "include("connection.php")" inside my code. I changed connection.php to /my/full/path/connection.php. I have some rename() calls with the relative path, and I changed to the absolute path. That worked for me. I hope it can help someone else.
Easy and logical way:
Checking the cron logs at /var/log/cron will give you very useful info
less /var/log/cron
Eg.,
My cron entry is * * * * * /usr/bin/php /cat.php <== Run cat.php every minute
The log file will contain an entry similar to the one below every time a cron entry is run
Jan 24 08:06:01 OlaTower CROND[13641]: (root) CMD (/usr/bin/php /cat.php)
Jan 24 08:07:01 OlaTower CROND[13641]: (root) CMD (/usr/bin/php /cat.php)
Here, the php command will be executed every minute and there will be an entry in the log file every minute
If the entry is not there then crond is not even picking that cronjob. If the log entry is there and still you are not getting the desired output then there is something wrong with the command/application logic
Are you sure it is not running? If you use exec, realize that you are running from cron and the full path for everything is required, so instead of cp, you'll need to use /bin/cp.
Centos 7
For the record (and it could work for other distros)
I had the next script
* * * * * /usr/bin/php -f /var/www/html/cron.php >/tmp/result.txt
But it failed to execute.
In the /var/log/cron log file, I found the next line
crond[2213]: (/usr/bin/php) ERROR (getpwnam() failed)
What is that?
It's simple, the syntax of corn is * * * * * user command (check user)
* * * * * someuser /usr/bin/php -f /var/www/html/cron.php >/tmp/result.txt
Using Ubuntu w/ Vesta :
The following command works perfect for me,
/usr/bin/php /home/admin/web/mydomain.com/public_html/mycode.php
Feel free to comment if you have any question, have a nice day :)
I was stuck too. I am using centos 7 and had to run few php scripts. I initially tried this
$crontab -e
& inserted the scripts to be executed at 12 midnight.
0 0 * * * usr/bin/php /var/www/html/cronjob/myscript.php
However in var /var/spool/mail/centos, it gave me an error in the mail there
/bin/sh: usr/bin/php: No such file or directory
So then I used wget like this,
$ crontab -e
0 0 * * * wget https://myapplicationurl/var/www/html/cronjob/myscript.php
This also gave me an error.
ERROR 404: Not Found.
Then I realized my mistake of specifying the folder, since the url will already be pointing to html folder, the folder from there i to be specified, like this
0 0 * * * wget http://myapplicationurl/cronjob/myscript.php
and it worked !!!
Hope this helps any newbie like me :)
if you php script has an include or require, you must provide the full path yours includes
wrong way
// relative path
require_once("../library/PHPMailer/PHPMailerAutoload.php");
Correct Way
// full path
require_once("/home/bitnami/library/PHPMailer/PHPMailerAutoload.php");
I had same problem with my php. Then I test execute php from root dir:
php -f /var/www/html/my_proj_folder/test.php
and got some errors regarding path to lib (included files), such as parse_ini with argument 'config.ini' <- has been taken from my global lib and lose path when it has been started from root.
So,
try to run your php-file (php -f your.file)
check relative path and try to run with absolute path
check permissions to your.php - it has to have executable flag x (you can see it ls -l your.php and set by chmod +x your.php)
put #!/usr/bin/php -q before <?php in your main/executable file

Running CodeIgniter cron on localhost

I'm trying to get a cron job to run every 5 min on my localhost. Using the Cronnix app I entered the following command
0,5 * * * * root curl http://localhost:8888/site/ > /dev/null
The script runs fine when I visit http://localhost:8888/site/ in my browser. I've read some stuff about getting CI to run on Cron, using wget and various other options but none make a lot of sense.
In another SO post I found the following command
wget -O - -q -t 1 http://www.example.com/cron/run
What is the "-O - -q -t 1" syntax exactly?
Are there other options?
-O - Means the output goes to stdout (-O /dev/null) would nullify any output. -q means be quiet (don't print out any progress bars), this would screw up the look of any log files. -t 1 means to only try once. If the connection fails or times out it will not try again.
See http://linux.die.net/man/1/wget for a full manual on the wget command.
Edit: just realised you're piping all this to /dev/null anyway, you may as well either omit the -O parameter or point that to /dev/null and omit the final pipe.
What I always do is use PHP in cli mode. Seems more efficient to me.
first setup a cron entry like :
*/5 * * * * /usr/bin/php /var/www/html/cronnedscript.php
cronnedscript.php should be placed in your root www folder.
then edit cronnedscript.php with:
<?php
$_GET["/mycontroller/index"] = null;
require "index.php";
?>
where mycrontroller is the CI controller you want to fire.
if you want the controller to only be run by crond ,as opposed through public www requests, add the following line to the controller and to the cronnedscript.php :
if (isset($_SERVER['REMOTE_ADDR'])) die('Permission denied');
I realize that this is a reference to Drupal, however they do a very nice job of explaining what each and every parameter is in the wget call.
Drupal Cron Explanation
If you want the more generic explanation, you can find it here.
Try this and save it by making a folder in the C drive with a .bat extension.
Then give the path of this script to task scheduler.
Then run the same.
C:\xampp\php\php-win.exe -fC:\xampp\htdocs\folder name\index.php controllername functionname

Categories