I want to try how to render html from R markdown file but from a bash script running as Cron jobs. I don't know why everything works fine, except running as Cron jobs. What I do:
My script is a demo script from Rstudio
---
title: "test"
author: "sms"
date: "24 maja 2015"
output: html_document
---
This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.
When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
```{r}
summary(cars)
```
etc.
This script works without any problem in Rstudio.
Next I try to run an Rmd script from terminal:
Rscript -e "require( 'rmarkdown' ); render('/home/sms/Dokumenty/R/test.Rmd', 'html_document')"
There wasn't any problem. It works.
So I create bash script
#!/bin/bash
Rscript -e "require('rmarkdown'); render('/home/sms/Dokumenty/R/test.Rmd', 'html_document')"
and changed chmod 755 test.sh
Also works like a charme.
But when put in Cron file (admin and user):
28 18 * * * sh /home/sms/Dokumenty/R/test.sh
It doesn't works
Any idea what am I doing wrong?
I had the same problem.
The issue is because I was running the Rscript as root, but Rscript should be run as souza, current user.
To fix that, I edited the crontab for user souza "sudo crontab -u souza -e" and the Rscript is run as souza and not as root.
Now it is working
Simplify, simplify, simplify.
First, I'd make it an Rscript, maybe called renderTest.R
#!/usr/bin/Rscript
library(rmarkdown)
setwd("/home/sms/Dokuments/R")
render("test.Rmd") # I usually use default arguments
Second, make the script executable (chmod 0755 renderTest.R).
Third, test the script. If you can run it as you, a cron job running as you should too.
Fourth, add the cronjob running as you to have the same rights.
Edit I just fixed a typo I copied from you: Documents/ not Documenty/.
I have the same problems.
But it would work if you try to use knitr::knit2html instead of rmarkdown::render
on idea why
Related
I want to use cron for execute a script periodically. I want to try a simple script first but it does not work.
This is my script (scritp.sh) which permission are 700:
#!/bin/sh
clear
echo "Hello!"
mkdir Hello
And this is the crontab file when I edit it with the command crontab -e:
SHELL=/bin/sh
* * * * * /home/padro/Documents/script.sh
EDIT:
I have that script on /home/padro/Documents folder. What I do after it is execute the command crontab -e for modify the cron file. In this file I put the shell that I want SHELL=/bin/sh and also the cron schedule expression * * * * * /home/padro/Documents/script.sh. This schedule teorically run the script every minute. Finally I save the file and when a minute passes I can't see the echo of the script on the terminal.
EDIT2:
I have added mkdir hello, because I don't know if the echo of the script is shown on the terminal. But the hello directory is never created.
Any output generated by a program called from cron will by default be emailed to the user owning the crontab (assuming local delivery of mail messages is possible). So I'd suggest that you look in your inbox on the local machine.
To save the output into a file, use a redirection in the crontab, or arrange for the script to write its output to a file.
Jobs started by cron does not run with a terminal, so you should not expect to see your terminal being cleared every minute by running this script through cron.
The Hello folder should have been created in the working directory used by the script (possibly your home directory). To make absolutely sure you know where the script's working directory is, use cd in the script to move to the correct location.
I do not have enough reputation to add comment.
My humble comment would be.
Is the cron file you mentioned via root?
cos chmod 700 a file would be only be executed by owner.
If you are using redhat linux, the user account you use on the first log in is user rights NOT root.
Reference link to a cheat sheet.
su - root
system will prompt root password
crontab -e
* * * * * /home/padro/Documents/script.sh
You can even run a test script, which I did encounter the similar situation as you when I first learnt scripting into your crontab-
* * * * * date > export/home/padro/Documents/testing.txt
If you could, restart the server.
Check if your directory is correct using the command
pwd in linux/unix.
I hope my comment based on my recent learning have helped you.
Edit 1: Remove clear in your script. Thanks...
Edit 2: I believe your Hello folder is created at the core of the root folder try looking for it... or the home directory of the user...
I'm trying to start a bash script(test.sh) from a second bash script that runs as a cronjob(startTest.sh) on Ubuntu 14.04.
Cron is running and both scripts work perfectly if called from command line.
startTest.sh looks like this:
#!bin/bash
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/local/sbin:/sbin:/usr/sbin:/bin:/usr/bin:/home/username/path/to/script
bash /home/username/path/to/script/test.sh
test.sh looks like this:
#!/bin/bash
touch it_works.txt
My crontab entry looks like this
* * * * * /usr/local/bin/startTest.sh
Best practice is generally not to use relative paths (unless you do an explicit cd) in scripts run as cron jobs.
crond is probably not running from whatever directory you expect it to. Depending on what user this cron job runs as, the script either does not have permission to create it_works.txt in crond's current working directory, or it is creating the file and you're looking in the wrong place.
I have a script used for zipping a database and site files, then dumps the output into a backup folder on the server. The script runs fine from the command line, but it will not work through cron.
After much research, I am thinking that cron cannot run it in its current form because it runs in a different environment.
Here is the script, saved as file_name.sh
#!/bin/bash
NOW=$(date +"%Y-%m-%d-%H%M")
FILE="website.com.$NOW.tar"
BACKUP_DIR="/backupfolder"
WWW_DIR="/var/www/website/"
DB_USER="dbuser"
DB_PASS="dbpw"
DB_NAME="dbname"
DB_FILE="website.com.$NOW.sql"
WWW_TRANSFORM='s,^var/www/website,www,'
DB_TRANSFORM='s,^backupfolder,database,'
tar -cvf $BACKUP_DIR/$FILE --transform $WWW_TRANSFORM $WWW_DIR
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME > $BACKUP_DIR/$DB_FILE
tar --append --file=$BACKUP_DIR/$FILE --transform $DB_TRANSFORM $BACKUP_DIR/$DB_FILE
rm $BACKUP_DIR/$DB_FILE
gzip -9 $BACKUP_DIR/$FILE
I currently have the script stored in /usr/local/scripts/
Is there something wrong with the above code that does not allow it to run through cron?
Which crontab should it go in? crontab -e from terminal, or /etc/crontab? They are two different files.
Several things come to mind: first, one of the most common problems with cron jobs is that generally crond runs things with a very minimal PATH (usually just /usr/bin:/bin), so if the script uses any commands from some other binaries directory, it'll fail. Where is mysqldump on your system (run which mysqldump if you aren't sure)? If this is the problem, adding PATH=/usr/local/bin:/usr/bin:/bin (or whatever's appropriate in your case) at the beginning of your script should fix it. Alternately, you can set PATH in the crontab file (put this line before the entry that runs your script).
If that's not the problem, my next step would be to capture the script's output, with something like:
1 1 * * * /usr/local/scripts/file_name.sh >/tmp/file_name.log 2>&1
... and see if the output is informative. BTW, as #tripleee mentioned, the format of your cron entry is suitable for the files crontab -e edits, but not for /etc/crontab. The /etc version has an additional field specifying which user to run the job as, e.g.
1 1 * * * eric /usr/local/scripts/file_name.sh >/tmp/file_name.log 2>&1
Best practice is to always use crontab -e (the resultant files are usually in /var/spool/cron/) and this works on every unix and linux platform I ever worked on.
Other common issues with cron execution are missing environment variables. Any environment variables set in .bash_profile (or .profile if you use korn shell) will not necessarily be present in the cron environment. This can be overcome by including them in your script.
As Gordon said, paths are another suspect. You can always full path you executables in your script (eg /bin/mysqldump). Some of the more cynical of us do this anyway to make sure we are executing what we intended as apposed to some other file of the same name in the current path.
I can only guess at your specific problem since you fixed it by creating /scripts, that perhaps the permissions on /usr/local/scripts directory did not allow execution by the cron user?
I have had to remove the extension (.sh) for cron to run in some instances.
So I fixed it. Not sure what the problem was, but this worked for me.
I originally had the scripts located in /usr/local/scripts/
I created a new directory here - /scripts/ and moved the scripts there. The new crontab -e command looked like this:
1 1 * * * bash /scripts/file_name.sh
Works perfectly. Again, I am not sure what the issue was before, but it works now.
I need to have my Java program run on a linux box once a day. So I created a simple file with just one line:
java -jar /opt/location/my_jar.jar
and put it in etc/cron.daily, assuming it would run once a day. But it doesn't run at all. I tried both to have the .sh extension, or simply the file name with no extension. Still, no luck.
I googled it and I'm getting quite a bit of conflicting info. Can someone please help?
EDIT:
I'm summarizing the place it is right now, based on the answers given by Satish and Mithrandir.
1.I created the run_conversions script using vi, to get over the problem with the end of line character on windows. Now the script is
#!/bin/sh
/usr/bin/java -jar /opt/location/my_jar.jar
2.I put it in /etc/cron.hourly.
3.Checking the log at /var/log/cron I'm seeing the it's starting run_conversions and finishing run_conversions every hour. So far so good.
4.But it doesn't seem like my jar file is running. I know this because when it's running properly it should update a database -- and the database is not updating.
5.Here's the strange thing: when I'm running cron.hourly manually, but calling
run-parts /etc/cron.hourly
the jar file is hit propertly, and the database is updating.
To sum it up: when running it through run-parts, it works. When leaving it to run hourly by itself, it doesn't.
Any ideas?
EDIT 2:
Following advice from Satish, Mithrandir and vahid I changed my run_conversions_loc to look like this:
#!/bin/bash
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bexport SHELL=/bin/bash
/usr/bin/java -jar /opt/tf/conversions/aff_networks2.jar > /opt/tf/conversions/runconversions.txt
I removed the script from cron.hourly and added this line to crontab:
*/10 * * * * /opt/tf/conversions/run_conversions_loc
The script now runs every 10 minutes, and is registered in the cron log like this:
Feb 24 09:30:01 backsome CROND[7933]: (root) CMD (/opt/tf/conversions/run_conversions_loc)
So far it looks good. But the database -- which it should update -- isn't updated.
Looking deeper into it, the jar file, aff_networks2.jar is looking for an ftr.properties file in the local directory -- the same directory where it's at. The file exists in this directory. But it's not read properly. I know this because in the output file, runconversions.txt, the value that should be read from the properties file is null.
Two things to complete the picture:
Everything in the conversions directory has 777 permissions. I know it's not recommended to give such extended permissions but I wanted to make sure (at least try) it's not the issue.
When I run the script from the shell by calling ./run_conversions_loc it runs, finds the properties file, and updates the database. I am logged into the shell as root, and I also created all the relevant files as root, and installed as root the line for calling the script in crontab.
Any ideas why isn't cron reading the properties file?
its probably your environment variables
does it work as the current user logged in when executing the script ?
if so
run:
env|egrep "(^PATH=|^SHELL=)"|awk '{print "export "$1}'
then take the output and put it on the top of your script and try another cron in 2 minutes from now to see if it worked
Updated answer in response to Eddy's Comment 24th Feb 2013.
I want to give you a crash course on crontab.
setting up crontab can be done via global /etc/crontab or under user as crontab -e (to edit specific user's cron) or crontab -l (lists - stored in /var/spool/cron for each user)
I see you are trying to attempt a run ever 10 minutes which is fine in /etc/crontab
The reason why I suggested giving the entire class path of your current shell is because most of the time the script is trying to use a unix command that is not available as part of the crontab's PATH (which resides right at the very top of /etc/crontab file itself)
To debug path issues its usually a good idea to watch the mailbox of the user that crontab is executing the task as :
so tail -100 /var/spool/mail/root and looking out for any messages related to that cron task as well as the cron logs itself as someone has suggested -
I do not think your problem is paths here though..
You are trying to run a java jar file and it may be that your jar file needs other files in that conversion folder and that when you are running it you are already in that folder....
so in your script you could run
cd /opt/tf/conversions/;
/usr/bin/java -jar aff_networks2.jar > /opt/tf/conversions/runconversions.txt
But since this is such a small script you could get away with placing the entire thing as a cron entry and bypassing a shell script altogether something like this
*/10 * * * * root cd /opt/tf/conversions/; /usr/bin/java -jar aff_networks2.jar > /opt/tf/conversions/runconversions.txt
Hope this helps solve this issue
Solution with example:
Run command manually on command line:
[root#04 cron.daily]# /usr/bin/java -jar /root/HelloWorld.jar
Hello World #1
Let create a script in /etc/cron.daily/test.sh and give execute permission:
#!/bin/bash
/usr/bin/java -jar /root/HelloWorld.jar
Notes: run dos2unix in case you have dos character issue or error /bin/bash^M: bad interpreter: No such file or directory
[root#04 cron.daily]# unix2dos test.sh
unix2dos: converting file test.sh to DOS format ...
Test it, voila!!
[root#04 cron.daily]# run-parts /etc/cron.daily
/etc/cron.daily/ldiscan:
kcore: Value too large for defined data type
/etc/cron.daily/test.sh:
Hello World #1
Change your file to:
#!/bin/sh
/usr/bin/java -jar /opt/location/my_jar.jar
Check if /usr/bin/java is actually where the command is istalled (which java).
Change the permissions of you file to be executable:
chmod +x /opt/location/my_jar.jar
My script is under /u01/software/aditya/script/ directory. Name of script is myscript.sh. I am able to run this script and getting output too. I am trying to set a cronjob for this script at 6.30 daily morning. I am doing this as root user. I have done following steps but not getting output.
crontab -e
30 06 * * * sh /u01/software/aditya/script/myscript.sh >> /u01/software/aditya/hello.log
:wq
but not getting any update in hello.log file :( . please help….
First check your cron log file which is usually in /var/log/syslog. There should be entries similar to
Sep 17 06:30:01 localhost CRON[17725]: (root) CMD (sh /u01/software/aditya/script/myscript.sh >> /u01/software/aditya/hello.log)
If not, your script has never been run. This could be due to a broken crontab file. You should make sure that this file always ends with a newline, better insert more than one at the end so that deleting one accidentally won't break the file.
If this line exists in the log file then your script has been run, but didn't generate any output. This can happen due to a different environment when being run via cron.
Also note that >> only redirects stdout, not stderr. If you want to redirect stderr too, then add 2>&1 at the end of the line.
Normally this is caused by a PATH problem. There is a very good chance that myscript.sh calls a command that is not available in the PATH that cron runs with. Some options to fix this are:
Make sure that every command in myscript.sh is a full path-reference (tedious)
Add source ~/.bashrc to the top of myscript.sh
Add export PATH=$PATH:<colon delimited list of paths necessary for myscript.sh to run correctly>
Pick one of the above, or you could also choose one of the options here: Hourly cron job did not run