PHP Cronjob changing sh root - php

Some setup background first:
I have a cronjob which runs a PHP file called worker_cronjob. All the file does is download my worker from git and the cronjob in cron.d looks like:
*/1 * * * * ubuntu /home/ubuntu/worker_cronjob >> /home/ubuntu/worker.log
It includes the worker_despatcher file
Which fires off a child process with (ROOT being an abolsute path to my directory):
$PID = exec(sprintf("%s > %s 2>&1 & echo $!", "php ".ROOT."/worker/encoder.php".$arg_string, ROOT."/worker/encoder.log"));
The problem is that under a cronjob this method is changing the way system commands are run, more specifically sh. So when I run a command like:
ffmpeg
It returns:
sh: 1: ffmpeg: command not found
After trail and error I have discovered this only happens from the cronjob, somehow it is changing the way directories are set, much like chrooting without me calling chroot.
I have looked at other threads and it says it use full paths when creating cronjobs and running files, however it's not my files that's the problem and they are all referenced via absolute paths, it is running installed programs where I get problems.
Does the absolute path apply to installed apps as well or is there a way to break this functionality to give me back the ability to just run a command with one word?

The behind reason is that cronjobs are run by the system, so they know nothing about your shell or user environment variables. You can say they run in a minimal environment.
A great detailed answer can be found in Reasons why crontab does not work.
Another way not shown in the above link resource is:
* * * * * PATH=/usr/bin; command >> /var/log/command.log

Related

Running a Cronjob on 1&1 Shared Hosting [Laravel]

In my Laravel application, I have created a scheduled task, as defined in a previous question that I asked. It essentially grabs data and updates a few tables.
I followed a help article on 1&1 about creating cronjobs.
To summarise this article it said the following.
SSH to your server, that you want to set up the new cronjob on, use whereis php to find the location of your PHP Binary, then use the crontab command to access the crontab and add a new job.
This will require the PHP path and the path to the script that is to be run.
The issue is when I run that command I get the following.
No crontab for [username]
So, I then Googled and it seems some shared hosts don't allow you to use or even access the crontab.
On my shared hosting server the path to php-7.1-cli is as follows /usr/bin/php7.1-cli
Now, Artisan is part of Laravel and requires a higher version of PHP than what is found in \usr\bin\php
Given this, for the cronjob I thought I'd be able to do something like this:
* * * * * /usr/bin/php7.1-cli /path/to/artisan schedule:run >> /dev/null 2>&1
Or
* * * * * /usr/bin/php7.1-cli /path/to/mynewable/artisan schedule:run >> /dev/null 2>&1
My folder structure is as follows:
root
/mynewable
But when I run either of these commands, nothing happens.
1&1 also has an inbuilt cron job creator but this only allows me to specify a URL path to a file that would run the necessary script.
Am I being prevented from using crontab? If so, giving a URL seems impractical as the user wouldn't need to validate, but making a path in web routes to run the Laravel scheduler seems a bit of a security hole.
You can create a executable cron.php in your public folder of laravel.
exec("/usr/bin/php7.2-cli -f /homepages/x/xxxxx/htdocs/artisan schedule:run 2>&1", $out, $result);
if(!empty($out)) {
echo implode("<br>\n\n", $out);
}
Now you can call http://example.org/cron.php
Of course you can put the cron.php in a protected directory so no one can call the cron.php.

Setting up a Cron Job on CPanel to executes a PHP script

As implied in the title, the Cron Job is supposed to execute a php file (update.php, to be specific). The php file then writes to a csv file stored in the same directory.
I have the time set to * * * * * so that it executes every minute. The command is written as follows:
php -q /home//public_html/wallboard/update.php
I don't believe this is causing any errors, though it also doesn't seem to write to the CSV file. When I visit update.php in a browser, however, it executes and writes to the CSV file immediately. I'm not experienced with Cron Jobs and I'm sure there's an issue, but I don't know what exactly that issue is. Let me know if you have suggestions/questions. Any help is appreciated!
Current Command:
* * * * * usr/bin/php -q /home/<user>/public_html/wallboard/update.php
update.php:
<?php
include('lib/HelpDeskView.php');
include('lib/WallboardDisplay.php');
include('helpdesk.csv');
$helpdesk = new HelpDeskView();
$text="\r\ntest,test,test";
file_put_contents( "helpdesk.csv" , $text, FILE_APPEND);
Since your script resides in your public_html directory you can use wget for your Cron Job
wget -O - -q https://yoursite.com/wallboard/update.php
-O - output is written to the standard output in this case it will go to the email address you specify in CPanel
-q quiet mode
IMHO the best way is to contact support and ask them about command line syntax.
This is how I'm doing it at my linux server using cPanel.
This runs script.php which is stored in public root. Course, replace <username> in command line with your username.
At another server I'm using same command line with /usr/bin/php instead of php at the beginning of line, but I'm aware that not all servers use same command line. Some require php-cli in command line instead of php, some don't "like" -f argument, etc. So try various combinations.
To find more suggestions check out this SO topic too: Run a PHP file in a cron job using CPanel
Important thing: When trying different commands wait at least a minute (this case) to see if it works because Cron doesn't fire your script immediately.
Try to execute the same command in PHP CLI and check if it gives you any error, you might be missing some libraries or references required for CLI execution.
/usr/bin/php -d register_argc_argv=On /home/USERNAME/public_html/DOMAIN/artisan AMIR:HOME

Shell script runs php files over and over again

I have a ridiculously simple shell script, nothing more than a few instructions to run some php files ...
#!/bin/bash
clear
cd /home/************** // Just for privacy here
php cron-cpt.php
php cron-lvt.php
php cron-plots.php
php cron-m.php
php cron-a.php
The script is called metrics.sh which is chmod'd and just sits in my local binary folder.
If I run the script from the command line, it works perfectly.
If I add the same script to the cron tab to run once a day, it runs over and over. I assumed the cron was the same as invoking it manually from the command line?
I'm using the same user to invoke in cron as logged on cmd line and have tried as root and a standard user, but the same results prevail.
Google has not been helpful with this. Any suggestions?
Add this to your cronTabs:
0 1 * * * /home/metrics.sh
Change the location to your metrics.sh's location.

Cannot run shell_exec in cron'd PHP, $PATH is not visible as well

I'm trying to implement a testing integration solution in our environment. The simple workflow is like this: I have a CentOS EC2 instance in AWS where there is a MySQL DB with rows representing tests to be run (each one has a unique id, absolute file path, started time, completed time, etc). These tests are actually python scripts (using unittest framework).
I have created a PHP script (my language of choice) that takes all the non-started tests from the DB and runs them locally using python or even py.test which I execute through shell_exec() in my code.
Before running the PHP script though, I also execute (at least the first time) the following bash script to setup a local testing environment using headless Firefox with WebDriver, Selenium Server and Xvfb for a "display":
#!/bin/bash
if [ `whoami` != "root" ] ; then
echo "Run as root!"
exit 1
fi
#Start X virtual frame buffer
/etc/init.d/xvfb start
#Add fake display to env
export DISPLAY=:99
#Start Selenium Server
java -jar /opt/selenium-server/selenium-server-standalone-2.33.0.jar &
If I run my PHP script from the terminal like this:# php script.php everything runs correctly, php calls shell_exec() which in turns runs python to execute the test through py.test using the fake display etc.
BUT, when I try to add this PHP script in a cron job it fails. My cron.d file looks like this:
* * * * * root /usr/bin/php /path/to/script.php >> /path/to/log.log
I have read online that a solution would be to create a shell script that will call the PHP script inside it and put that into cron instead. I tried that and it seemed to do something but it stuck in another place (in my shell script first of all I had export DISPLAY=:99 just in case, so the python script will see the virtual display but I'm not sure if needed).
Anyway, following the above road, somehow made py.test to execute but then it throws an exception when it tries to locate the Firefox binary (which is located at /usr/local/bin/firefox). It seems that the shell script cannot see the $PATH. But I have also read the following: a shell script that executes another script inside it (PHP in our case) actually spawns a child for this, so is not always true that this child can see the $PATH even if set on the parent script? I'm not sure about this.
Can you help me? What's the best way to have all of the above run in cron?
How to make the PHP or shell script see the $PATH? (if that's the way to go at least)
You can export PATH in the beginning of your cron command.
Find the correct PATH
$) echo $PATH
/some/path:/some/other/path
In your crontab, write
* * * * * export PATH="/some/path:/some/other/path" && /usr/bin/php /path/to/script.php >> /path/to/log.log
Alternatively, you can set it in the beginning of your crontab file as well as shown here
Since you are setting the value of the DISPLAY environment variable and starting the xvfb sever, you should consider setting the path as well within your shell script and run the shell script as the cron job (instead of the php script I use in my example)
Create a crontab job from root user and remove root from: * * * * * root /usr/bin/php /path/to/script.php >> /path/to/log.log.

Crontab in Plesk

I'm trying to run a test script using crontab within Plesk. The php file simply emails me a message
mail('me#somewhere.com','Cron Test','Test');
My path to php is /user/bin/php
I have entered * in every field, to run the script every minute with the following command:
/usr/bin/php -q /usr/httpdocs/crontest.php
However, the script is not being run.
Can anyone help?
I'm probably missing something simple, I've never used cron before.
Any advice appreciated.
Thanks.
I would start by getting it to write to a log file. eg:
* * * * * /usr/bin/php -q /usr/httpdocs/crontest.php >> /a-location/crontest.log 2>&1
This will at least give you any obvious errors like not being able to find php etc.
I found that when using the user based cron in plesk, there are a number of issues:
first I found that you should reference the script from the virtual domain. If your script has an absolute address of /var/www/vhosts/domain.com/httpdocs/email-this.php, you should reference it as httpdocs/email-this.php in the crontab.
Second, the script has to have very particular permissions, but not sure what they "must be." apache:apache is all that ever worked for me. Even with the group write permission set, user still had to be apache... weird.
Third, the easiest way to do the testing was to edit the crontab directly instead of going back into plesk every time I needed to make a change... Edit your crontab like this:
crontab -u [filesystem-username] -e
Fourth, I could never get the crontab to write to a log file outside of httpdocs (I tried statistics/logs/cron_log every way I could think of... lol... no dice). I ended up just adding the MAILTO directive at the top of the crontab file during testing:
eg:
MAILTO=you#domain.com
## * * * * * php -q httpdocs/cron.php
Also see this if you have Plesk 10 or above: http://shaun.net/2011/09/solving-plesk-10-3-1-cron-issues/
I had to do this
/usr/local/psa/bin/server_pref -u -crontab-secure-shell "/bin/sh"
to get this (example) working: wget -O - http://www.yourdomain.com/cron.php

Categories