I have a bash program that picks data from a file and delivers these data (if fulfilling a threshold) to another file.
It is a php script inside the bash script named smaoutput-analyse.sh
When executed from the shell it functions perfect.
When executed as a cron job as root is is executed correct, but there is no output.
Here is the output from grep -i cron /var/log/syslog
Aug 14 16:06:01 raspberrypi CRON[6705]: (root) CMD (/home/pi/scripts/SBFspot.sh > /home/pi/test/smaoutput.txt 2>&1 )
Aug 14 16:06:01 raspberrypi CRON[6706]: (root) CMD (/home/pi/test/smaoutput-analyse.sh > /dev/null 2>&1)
The information is (as mentioned before) correctly added when running fom the shell
#!/usr/bin/php
<?php
echo " Programm to read smaoutput.txt",PHP_EOL;
// etc etc
`if(!file_put_contents("sma_saved_data.txt",$sma_saved_data_string,FILE_APPEND)){
// failure
echo "error opening the file sma_saved_data.txt for writing",PHP_EOL;
}
// etc etc
?>
Here are the crontab lines:
# Every minute result of SMA
*/1 8-22 * * * /home/pi/scripts/SBFspot.sh > /home/pi/test/smaoutput.txt 2>&1
# afterwards read and save in file
*/1 10-20 * * * /home/pi/test/smaoutput-analyse.sh > /dev/null 2>&1
I think I have set file permissions correct +rw for the files and +rwx for the bash
What did I miss
You should check the following issues:
Are all the environment variables the same? So call printenv from bash and create a cron-job */1 8-22 * * * printenv > /tmp/printenv.txt --> Compare the ouput of file /tmp/printenv.txt with printenv from bash
Are you executing with the same user and the same permissions? Execute echo "$USER" and create a cron-job */1 8-22 * * * echo "$USER" > /tmp/user.txt --> Compare the ouput of file /tmp/user.txt with echo "$USER" from bash
Check the path you executing the script. Call pwd from bash and create a cron-job */1 8-22 * * * pwd> /tmp/pwd.txt --> Compare the ouput of file /tmp/pwd.txt with the ouput of pwd from bash
Realy interesting.
This was my first post and I received quite a swift response.
Thank you!
The solution was simple: provide the full path to where you want to keep the file.
Remark: To be shure that everything will be executed I alway put cronjobs in a root crontab and not in a user crontab.
Maybe that is "smart thinking" but not so smart acting.
I would appreciate to get some comment on this root cronjob idea.
The post about executing printenv, echo "&USER" and pwd both from bash and from cron was interesting.
The printenv from bash gives a lot of information, amongs which SHELL=/bin/bash, SSH_CLIENT, SSH_TTY. MAIL, PATH, SSH_CONNECTION and lots more starting with LS_COLORS, the printenv from cron is just 6 lines HOME=/root, LOGNAME=root, PATH=/usr/bin, LANG=en_GB,UTF-8, SHELL=/bin/sh and PWD=/root
The echo "&USER" from bash gives pi, whilst from cron gives a blank file
The pwd from bash gives /home/pi/test and from cron /root
These results are understandable.
Can I learn from it that I should create cronjobs as user pi and not as user root?
Related
I'm using crontab to call a php script.
In this script there is
error_log('test');
When the script is executed from http or direct command line like
php -f script.php
Everything is fine, my error is log.
But when called from cron it's not working.
Here is my cron
* * * * * -u www-data /full_path_to/php -f /full_path_to/script.php
Here is what I tried :
error_log with arguments :
error_log('test', 3, '/full_path_to/error.log');
changing error reporting :
error_reporting(E_ALL);
ini_set('display_errors','On');
ini_set('error_log', '/full_path_to/error.log');
cron call ending with > /full_path_to/error.log 2>&1 (don't know if useful)
For http the error_log path is set from htaccess.
I'm lost with php cli...
I can see the cron execution working every minute (syslog), so it should be a PHP config problem ?
Thanks a lot if you can help.
Edit : Cron is executed with "-u www-data"
Here is the call I see in syslog :
CRON[13921]: (www-data) CMD (-u www-data /usr/bin/php -f /fullpath/script.php > /fullpath/error.log 2>&1)
I was facing the same problem but was able to fix it after reading the manual entry for php.
Initially I had something set like:
/usr/bin/php -f /path/to/php/script.php -c 1426 >> /tmp/script.php.log 2>&1
I was able to fix it by changing the line to:
/usr/bin/php -f /path/to/php/script.php -- -c 1426 >> /tmp/script.php.log 2>&1
As per the manual entry the syntax is:
php [options] [ -f ] file [[--] args...]
Also,
args... Arguments passed to script. Use '--' args when first argument starts with '-' or script is read from stdin
Going by that, my cron command becomes:
/usr/bin/php -f /path/to/php/script.php -- -c 1426 >> /tmp/script.php.log 2>&1
and it works!
You have to be aware that there are user specific crontabs and a system wide crontab.
When you are logged in as user foo and type crontab -e in console this will allow you to edit your own user specific crontab. All defined cron tasks will be executed as user foo. This is even true for user root. AFAIK this way you simply can not change the user under which a cron task will be run.
Quite different is the file /etc/crontab. This is the system wide crontab. Within that file you can change the user of a cron task like this:
* * * * * www-data /full_path_to/php -f /full_path_to/script.php
I had in fact two problems :
1) My cron was executed with php.ini for php-cli. I used the -c flag to load the good one.
2) I was relying on $_SERVER to declare important constants using variables that do not exist in cli-mode. Now if these variables are not set I parse commande line vars with getopt()
I am trying to run a php file every night at a certain time using crontab, however the php needs to be running as a www-data because of the directory permissions. To run it as www-data I am using the root crontab and changing the user in there, like so:
* 20 * * * sudo -u www-data /usr/bin/env TERM=xterm /path/to/dailyProc.sh
dailyProc is as follows
today=`date +"%d%m%y"`
year=`date +"%y"`
dm=`date +"%m%d"`
`tar -zxf /path/to/input/$today.tgz -C /path/to/output`
echo "starting data proc"
`/usr/bin/php5 -f /path/to/dataproc.php date=$dm year=$year`
echo "data proc done"
All other commands in dailyProc.sh work but the php doesnt run. The php is using an output buffer and writing it to a file, which works fine calling it from the command line but doesnt work when calling by cron.
I can also definitely run dailyProc.sh from the command line as www-data using
sudo -u www-data dailyProc.sh
and everything works as expected.
Is there any reason I would not be able to run this php file in dailyProc.sh using crontab when everything else in it works?
Cron can be run per user too.
crontab -u www-data -e
This works for me:
* 20 * * * su - www-data -C "/path/to/dailyProc.sh"
You do not need to use su or sudo in a crontab entry, because the 6th column is for the user name anyway. And you don't need to start a terminal, because you won't see it anyway. Hence, the following should do:
* 20 * * * www-data /path/to/dailyProc.sh
The Syntax error: word unexpected… you mentioned in a comment appears to be inside your code. Try running the script from the command line and start debugging from there.
To do this I used curl inside dailyProc.sh
today=`date +"%d%m%y"`
year=`date +"%y"`
dm=`date +"%m%d"`
`tar -zxf /path/to/input/$today.tgz -C /path/to/output`
echo "starting data proc"
`/usr/bin/curl "myserver.com/dataproc.php?date=$dm?year=$year"`
echo "data proc done"
This is my very first time running a cron job on Elastic Beanstalk (EB). After deploying my code, it seems the cron job is created and running but the PHP script is not executing correctly. Here's my set-up.
In my .ebextensions folder I have a file called 01run.config.
container_commands:
01_remove_old_cron_jobs:
command: "crontab -r || exit 0"
02_cronjobs:
command: "cat .ebextensions/cron_jobs.txt > /etc/cron.d/cron_job && chmod 644 /etc/cron.d/cron_job"
leader_only: true
In my .ebextensions folder I also have a cron_jobs.txt file. Please note that I have an line break at the end of this file as instructed by another stackoverflow post. In my example below I am running the command as ec2-user but I also tried root.
* * * * * ec2-user /usr/bin/php -q /var/app/current/tests/cron.php
After deploying my code, I can see that the file /etc/cron.d/cron_job has been created. I can also see the cron job running every minute when I run sudo tail /var/log/cron.
[ec2-user#ip-xxx-xxx-xxx-xxx ~]$ sudo tail /var/log/cron
Apr 13 12:54:53 ip-xxx-xxx-xxx-xxx crontab[26093]: (root) DELETE (root)
Apr 13 12:55:01 ip-xxx-xxx-xxx-xxx crond[1230]: (*system*) RELOAD (/etc/cron.d/cron_job)
Apr 13 12:55:01 ip-xxx-xxx-xxx-xxx CROND[26128]: (ec2-user) CMD (/usr/bin/php -q /var/app/current/tests/cron.php)
Apr 13 12:56:01 ip-xxx-xxx-xxx-xxx CROND[26139]: (ec2-user) CMD (/usr/bin/php -q /var/app/current/tests/cron.php)
Within /var/app/current/tests/cron.php I have some code that adds a row to a MySQL database (hosted on RDS). But nothing is being added to the database.
I then tried running the cron command directly through my terminal window:
$ /usr/bin/php -q /var/app/current/tests/cron.php
And it runs without error and adds the record to the database. I am logged in as ec2-user in terminal.
Have I missed something? Or is my cron job code set-up incorrectly?
I had a similar problem with a php script that was trying to access an AWS RDS database. Is your php script getting the database details with $_SERVER['RDS_xxxx']? If so, those RDS_xxxx variables don't exist in the environment when the php script is run by cron.
In order to fix this, I added the variables to the beginning of the cron file:
RDS_HOSTNAME=<my_database_hostname>
RDS_PORT=<my_database_port>
RDS_USERNAME=<my_database_username>
RDS_PASSWORD=<my_database_password>
RDS_DB_NAME=<my_database_name>
* * * * * php /path/to/my/script.php
Login via SSH and check if generated cron job file/etc/cron.d/cron_job have unix line ending i.e. ASCII text not win i.e. ASCII text, with CRLF line terminators.
To check the line ending refer the answer here.
Note: If you have windows line ending then you will have to convert the line ending of file .ebextensions/cron_jobs.txt, for that you can use dos2unix or similar program.
I had a similar problem with my RDS_ variables on AWS, I followed this discussion and it works.
This was my cronjob before:
RDS_HOSTNAME=<my_database_hostname>
RDS_PORT=<my_database_port>
RDS_USERNAME=<my_database_username>
RDS_PASSWORD=<my_database_password>
RDS_DB_NAME=<my_database_name>
* * * * * cd /var/app/current && bin/cake notifications send_push >> /var/tmp/notifications.log 2>&1
And changed to this:
* * * * * . /opt/elasticbeanstalk/support/envvars cd /var/app/current && bin/cake notifications send_push >> /var/tmp/notifications.log 2>&1
And now I can access them like: $_SERVER['RDS_HOSTNAME']
I am trying to run a crontab on Ubuntu, I think I get the general idea of how to create a crontab
I did the following...
1) run command crontab -e
2) add entry 04 22 * * * /var/www/update_ranks >> /root/update_ranks.root.txt
3) check a text file was created under root/ named update_ranks.root.txt at the specified
time.
The file update_ranks.root.txt is empty and the php file is not executed, what am I doing wrong?
If update_ranks is a bash file try adding sh before the script sh /var/www/update_ranks
By the way, check if you are doing that as root user or user with writing rights to /root. Try sudo crontab -e.
EDIT:
If it's a PHP file, you need to execute it in php /usr/bin/php /var/www/update_ranks and if the file has extension, use this: /usr/bin/php /var/www/update_ranks.php
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.