I have cronjobs that execute PHP files at pre-determined times. These scrips can take over an hour to complete. I want to be able to physically monitor the scripts. I have logs, of course, and lots of ways to handle errors, but sometimes I just like to see what's happening.
Previously I did this on Windows where I would schedule a task which would launch in a shell that would remain open while the task ran.
Can I do this on Linux? Using SSH? Something perhaps like using screen with the cron? I'm using the AWS version of Linux.
Thank you.
The easiest (though sligtly dirty) way to do this, is to set an environment variable in crontab:
* * * * * THIS_IS_A_CRON=1 /path/to/script
Then, to see if they're running on your machine:
ps auxe | grep THIS_IS_A_CRON
That'll list all proces (if any) that were started with the THIS_IS_A_CRON environment variable
If all you're after is a window where you can see the output of the script while it's running, it's really nothing too different from having:
* * * * * /path/to/script 2>&1 >> /random/output/file.txt
And opening a terminal that tails the file:
tail -100f /random/output/file.txt
You can pipe output of a cronjob to a logfile, and you can use unix tools (tail, watch, etc) to view all the output as it goes, e.g. the following redirects STDERR as well as STDOUT to a log file:-
/usr/bin/really_long_script.sh > /tmp/script.log 2>&1
tail -f /tmp/script.log
If the script is generating output, that you would like to monitor, let it log this and use tail -f on the log.
Using screen for this is overkill.
Related
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
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.
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
I've been experimenting with cronjobs recently and have it setup like so:
crontab:
SHELL=/bin/sh
MAILTO=me#me.com
26 11 * * * wget http://diruser:pass#domain.com/path/to/file.php
Within the php file it runs is a SQL query which at the moment just runs an insert. This works fine and runs the insert but when I look at the email it produces it says this:
email:
wget http://diruser:pass#domain.com/path/to/file.php:
Command failed with exit status 1
I was just wondering if anyone knows why it would return command failed? It obviously doesn't fail but the email response makes me think I've done something wrong somewhere.
Also, is it good practice to put the file the cron is calling inside a password protected directory or is there a better way around it (such as checking that the request ip is that of the server or something).
Most likely, wget throws an error because it cannot save the result. By default wget will try to store thr result on disk. When running in a cron job, the working directory is (usually) /. You , as a user, probably cannot store a file there.
Instead, tell wget to drop the result, or pipe it to /dev/null. Fox example:
wget -O - -q http://diruser:pass#domain.com/path/to/file.php
I have no idea why error is produced. But in my opinion this is not good practive to call PHP via wget. You can write PHP script which will not be accessible over Apache (or Nginx or other HTTP server) and can be called from cron:
SHELL=/bin/sh
MAILTO=me#me.com
26 11 * * * php /path/to/file.php
And better way is to call it like an separated user, phpuser for example, who will have only permissions that script needs.
Try:
26 11 * * * /usr/local/bin/wget "http://diruser:pass#domain.com/path/to/file.php" > /dev/null 2>&1
Or
26 11 * * * /usr/bin/wget "http://diruser:pass#domain.com/path/to/file.php" > /dev/null 2>&1
1. crontab needs the full path to the command, in order to run it
2. wget will try to save the response of the file.php, if it doesn't have the necessary permissions, it will fail. That's why you should redirect the output somewhere else, other than a file, which is accomplished by > /dev/null.
There are three standard sources of input and output for a program, i.e. STDIN, STDOUT, STDERR, respectively numbered as 0, 1, 2.
When you redirect the output by using the greater-than >, if you don't explicitly mention which one you want to redirect, the default one is STDOUT (1). Thus, we will redirect all STDOUT output to null/trash, and all errors 2>&1 to STDOUT, which in turn will go to trash, as denoted by the previous rule.
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