Creating a cron job with PHP and Apache - php

I have Apache running on Debian with PHP 5.4.
PHP-cli is installed.
My directory structure for the web project is:
- /myproject
- /src
- /controller
- getProviders.php
- /model
- /public
- ClassLoader.php
I want to create a cron job to execute getProviders.php every 5 minutes. This is as far as I have come:
*/5 * * * * /usr/bin/php /var/www/myproject/src/controller/getProviders.php
It doesn't work because I have a require_once in getProviders.php requiring ClassLoader.php, but he can't find it.
require_once "../ClassLoader.php"
getProviders.php works when executed via URL.
I'm not new to PHP development, but new at configuring the server around it.
What do I have to do to make it work. I'm guessing I have to set the include path, but I have no idea to what exactly.
Thanks in advance for your help.

Create a shell script like this in /usr/sbin (For Example: getProviders)
#!/bin/bash -x
cd /var/www/myproject/src/controller/
php getProviders.php
give permission
chmod a+x /usr/sbin/getProviders
in /etc/crontab
*/5 * * * * root /usr/sbin/getProviders
the problem is probably due to inclusions not in absolute value in the php script

To make sure the require_once will always work, you could use dirname(__FILE__) + the path relative to the getProviders.php
In your case this would be:
require_once(dirname(__FILE__)."/../ClassLoader.php");

Change to the right workdirectory.
You could do this with the cd command or inside your PHP script with the chdir() function.

Related

cron commands do not run, getting output /bin/sh: 1: php: not found

I have the following inside my crontab -e
0,30 * * * * cd /usr/local/bin && php /var/www/artisan my_command > /var/www/storage/logs/cron.log 2>&1
But I get the following inside /var/www/storage/logs/cron.log.
/bin/sh: 1: php: not found
I tried running the following for reference:
# which php
/usr/local/bin/php
# whoami
root
I am running cron from inside a docker image (OS: Ubuntu) in a Laravel project.
I tried changing the path in different ways, but it still gave the same error.
There were a lot of similar questions, but I didn't manage to find my answer...
The current directory isn't in the PATH (and it shouldn't be).
Simply skip the useless cd command and run /usr/local/bin/php instead:
0,30 * * * * /usr/local/bin/php /var/www/artisan my_command > /var/www/storage/logs/cron.log 2>&1
Thanks to #Some programmer dude.
I would like to add some details, since I was not originally able to understand what he meant.
Basically when I was calling php cron would look for the file in every folder inside the PATH, but NOT the current directory (unless it is inside the PATH).
Sure, simply removing the cd is the best solution.
But to better explain the issue another perfectly working solution would be this one:
0,30 * * * * cd /usr/local/bin && ./php /var/www/artisan my_command
The only difference here, from the command I was originally using, is that I am specifying to use the current path with the ./.

How dynamically set variables on Cron?

I'm trying to make a cron file to be placed in /etc/croon. d. My problem is I don't want keep this file updated, so I'm looking for a way to get the software version dynamically from a file.
I have few other variables, but for now I think the problem is with $ (cat /software/VERSION), it works very well in shell script but not on croon.
#!/bin/bash
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
APPLICATION_ENVIRONMENT=SOME_STRING
VERSION=$(cat /software/VERSION)
HOME=/var/www/scripts/$VERSION/cron
CRON_LOG_DIR=/var/www/scripts/logs
*/2 * * * * root cd $HOME & php -f $HOME/do_something.php $APPLICATION_ENVIRONMENT >> $CRON_LOG/something.log
This is the output on cron log:
(root) CMD (cd $HOME & php -f $HOME/do_something.php $APPLICATION_ENVIRONMENT >> $CRON_LOG/something.log)
(CRON) ERROR chdir failed (/srv/www/tdp/public/$VERSION/backend/cron): No such file or directory
Cron table is not a shell script! You cannot put variables there.
You have to call a script from the cron and do the logic there.
If you really have to set environment variables in cron, you can do it like this
*/2 * * * * root SHELL=/bin/bash VARIABLE=something cd $HOME & php -f $HOME/do_something.php $APPLICATION_ENVIRONMENT >> $CRON_LOG/something.log
But it might not work and you might make a mistake (I am not 100% sure I made the syntax right; it's not easy and it's not necessary).
You should put as little logic to cron as possible.
Also, you should not edit the cron file directly; use crontab -e instead, it will check if you made correct syntax.
So you should do
*/2 * * * * user /home/user/your-script.sh
and set the variables in your script. (You also shouldn't run programs as root if it's possible.)

AWS Elastic Beanstalk: Running Cron.d script, missing Environment Variables

I'm trying to run a PHP script that is triggered by a cron script (in cron.d). The script is triggered properly but it is missing the Elastic Beanstalk "Environment Variables" that are stored in the $_SERVER superglobal. The script is being run as the user "root" for now, but it's not in the same environment that has the environment variables. The variables are set correctly, if I run the script from a full shell it runs just fine.
Where are the "exports" for these variables? Where do they get set? I found the SetEnvs for Apache in /etc/apache/conf.d/aws_env.conf. I can't find anything in the user's .bashrc, .bash_profile, etc. Is there a workaround? A better way to do this?
Thanks.
While searching for solutions to the same problem I ran into this blog post: http://sebgoo.blogspot.nl/2013/10/elastic-beanstalk-cron-command-and-rds.html. To summarize, you can load the Elastic Beanstalk environment variables using the opt/elasticbeanstalk/support/envvars file:
0 3 * * * . /opt/elasticbeanstalk/support/envvars; some_command
Hope this helps!
I just found this, using
grep -r "export MY_VAR" /
EDIT: Amazon seems to move the file location from time to time. Current location is:
/opt/elasticbeanstalk/support/envvars
So I think I'll just include (source [file path]) that in my script before calling my php script. Still seems like a funky way to do things. I'm still in for better solutions.
I was running PHP via bash script triggered by cron. So to setup the environment, I would do something like this:
#!/bin/bash
source /opt/elasticbeanstalk/support/envvars
php -f my-script.php
See #userid53's answer below for PHP solution.
I spent several hours trying to figure out how to pass Environment Variables to PHP CLI. I tried:
setting in ebextensions config: $ source /opt/elasticbeanstalk/support/envvars.d/sysenv
setting all my Environment variables to config file.
No matter what I tried, env variables won't pass to PHP CLI.
When I log to my EC2 instance as ec2-user and do this: $ echo $ENVIRONMENT I get prod. If I do it as $ sudo su and then $ echo $ENVIRONMENT I get prod.
If I manually run the PHP CLI file (used in cronjob) my script works. When it runs automatically (via cronjob) Environment Variables are not passed to my script.
Here's what I did. Put this in your cronjob entry script:
$variables = '/opt/elasticbeanstalk/support/envvars.d/sysenv';
if (file_exists($variables) && is_file($variables)) {
$contents = file_get_contents($variables);
foreach(explode("\n", $contents) as $line) {
if (empty($line)) continue;
$new_line = str_replace('export ', '', $line);
$first_part = strpos($new_line, '=');
$last_part = substr($new_line, $first_part, strlen($new_line));
$variable_value = str_replace(array('=', '"'), array('',''), $last_part);
$variable_name = substr($new_line, 0, $first_part);
putenv($variable_name."=".$variable_value);
}
}
It extracts each line from /opt/elasticbeanstalk/support/envvars.d/sysenv file, removes the export part, gets the variable name & value, and sets it via putenv() function.
It's works for me with a Laravel Project
* * * * * root . /opt/elasticbeanstalk/support/envvars && /usr/bin/php /var/www/html/artisan schedule:run 1>> /dev/null 2>&1
For a non Laravel Project you can test that:
* * * * * root . /opt/elasticbeanstalk/support/envvars && /usr/bin/php /path/to/your/script.php 1>> /dev/null 2>&1
Hope this helps!
in version 3.0.3 it has changed again, use this to export your envars in command line
file="/opt/elasticbeanstalk/deployment/env"
while IFS=: read -r f1
do
export $f1
done <"$file"
I know this is an old thread but I recently needed to do something similar in a Node.js environment deployed on Elastic Beanstalk; for what I could tell, the file /opt/elasticbeanstalk/support/envvars is not present on Node.js environments. I ended up writing a Python script that loaded the environment variables from /opt/elasticbeanstalk/bin/get-config, and then executing my Node.js script from there.
The code I ended up using was:
#!/usr/bin/env python
import os
import subprocess
from subprocess import Popen, PIPE, call
import simplejson as json
envData = json.loads(Popen(['/opt/elasticbeanstalk/bin/get-config', 'environment'], stdout = PIPE).communicate()[0])
for k, v in envData.iteritems():
os.environ[k] = v
call(["babel-node", "/var/app/current/<script_name>.js"])
Hope this helps anyone needing to do the same.
For the complete configuration I deployed, you can refer to my original post How to set environment variables in Amazon Elastic Beanstalk when running a cron job (Node.js)
I added the following line to my shell script:
source /opt/elasticbeanstalk/support/envvars .bash_profile
So my script, which is executed by the crontab, looks like this:
#!/bin/sh
source /opt/elasticbeanstalk/support/envvars .bash_profile
# do some php stuff
In case you need something similar for CodeIgniter:
* * * * * root . /opt/elasticbeanstalk/support/envvars && /usr/bin/php /var/www/html/index.php controller method
Example:
* * * * * root . /opt/elasticbeanstalk/support/envvars && /usr/bin/php /var/www/html/index.php tasks pushNotification
A more descriptive alternative:
* * * * * root source /opt/elasticbeanstalk/support/envvars && /usr/bin/php /var/www/html/index.php tasks pushNotification
AWS and EBS are changing the location of the env vars from time to time. At the current time, I was able to retrieve the env vars from the following path (I've python EBS)
/opt/python/current/env

Problem running a small script as cron job

I am problem scheduling and running a script through cron job. I am on linux (ubuntu), it is a VPS.
What I am doing is I have put this line in crontab file that is here: /etc/crontab
I wrote:
*/15 * * * * www-data php /var/www/abs/phpscript.php
I have given 777 to the file and after writing above in crontab , I run command:
crontab crontab
Then after almost some time I got the mail in my /var/mail/username file that says: /bin/sh: root: not found
So I am unable to understand what is the problem.
I also run phpinfo and it shows the third variable as APACHE that probably means that PHP is running as apache module.
Please tell what can be the possible solution.
thanks in advance to every one who will try to solve my problem.
You can try also to run it using "wget -q -O"
or
*/15 * * * * lynx -dump "url" > /dev/null
Wget examples:
*/15 * * * * wget -O /dev/null 'http://www.mydomain.com/document.php?&user=myuser&password=mypass' >/dev/null
If you need to post data you can use
--post-data "login=user&password=pass"
*/15 * * * * wget -O /dev/null 'http://www.mydomain.com/document.php?&user=myuser&password=mypass' --post-data 'foo=bar' >/dev/null
If you edited /etc/crontab, you should re-read the warning at the top of the file:
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
Running crontab(1) on the /etc/crontab file probably contaminated the root user's crontab(5) file (the one stored in /var/spool/cron/crontabs/). I suggest running crontab -e as root to edit the crontab file, and remove all the entries that are identical to the entries from /etc/crontab. (Maybe you just contaminated your own personal crontab(5) -- if crontab -e as root didn't show anything, run crontab -e under your own personal account and see if the system-wide entries were duplicated into your own crontab(5).)
I don't know what file you ran chmod 777 on, but that was probably unnecessary. You really should set your permissions to be as strict as possible to confine the results of malicious attacks or unintentional mistakes.
You are running a crontab as a user, which means you can't specify the user in the cron.
The template you borrowed your example from was for a system (root) cron.
Remove the username and try again.

Adding php script to cron

What should be given as the url to the script while adding it to cron scheduler. The script is at domain.com/scripts/script.php
PS:I am using cPanel
If you add the line
#!/usr/bin/php
to the beginning of your file (use 'which php' to find out your actual directory) and change the file mod to "executable", you should be able to run it just by calling like your second choice,
/public_html/scripts/script.php
I hope that works for you.
Here's a copy / paste out of one of the cron jobs that I run:
00 7 * * 1,2,3,4,5
/usr/local/bin/php
/home/processing/process.php
You must use the absolute path to the PHP binary as well as the absolute path to the script itself.
none of these.
but full absolute path from the root of the filesystem.
you can see that path with this code
echo __FILE__;
I had the habit of changing directory cd /var/www/vhosts/somesite.com/httdocs before running script with /usr/bin/php -f ./scriptname.php 2>&1 all in the same line on crontab.
I redirect the error output to get notified by email in case an execution error occured.
From crontab :
MAILTO=emailnotifications#mail.com
* * * * * cd /var/www/vhosts/domain.com/httpdocs/; /usr/bin/php -f testmail.php 2>&1

Categories