What is preventing my cron job from running - linux

I have created a list of cron jobs (see below) using sudo crontab -e in the root crontab file. When I run the commands individually on the command line, they work fine, however none of the jobs are run by cron. Any help would be appreciated. Do I need to add something else into the crontab file?
48 * * * * sudo gzip -k /calcservergc.log.*
49 * * * * for file in /calcservergc.log.*.gz; do sudo mv $file $(hostname).${file:1}; done
50 * * * * sudo rm $(hostname)..log..gz

sudo
The sudo command may not work in a crontab. Generally you need a password to run sudo but there might be a way to have it run without a password when running in a cron job. This would not be recommended however to attempt.
cron
You'll need to run the cron as a user that has access to do what you need to accomplish. Cron runs with a short list of specific paths. By default that list is pretty short. On a linux box I use the path is /sbin:/usr/sbin:/bin:/usr/bin.
Also, the paths need to be more specific. Cron doesn't run as a normal user so you have to be more specific with paths and output of those commands.
For instance, on the first command, where will the gzip file be placed?
logrotate
It looks like you're trying to zip a log file, then move log files, then remove old log files - this is exactly what logrotate accomplishes. It would be worth installing. Logrotate solves problems like the log file being opened when you run this command - generally the process that has the log file opened doesn't lose the file handle even if you rename it so the log continues to be written to even after you move it. It also handles the problem of keeping an archive of the recent log files, like syslog.1.gz, syslog.2.gz, syslog.x.gz or as many back as you have storage space for or want to keep for posterity.
Summary
Don't use sudo in cron
Be specific in paths when running commands in cron
Use logrotate to accomplish this specific task in your question

I don't have 50 points of reputation so can't comment on your question, so I'll try to say it in one shot.
I detect a possible problem with your 3 commands each called at one minute apparts. Let's say the first operation takes more than one minute to run (shouldn't happen but in theory it could), your second call won't work or worst, it could work on half the data). You don't want to loose time by, lets say, put 5 minutes delay between your commands, that would be a lost of time.
What you could do is create a shell script in which you put the 3 commands. This way it will prevent your operations to "crash". So just put your 3 commands in a script shell and they will be executed one after the other.
Then put your file in a place like /bin (you can also create a symbolic link with ln -s) and call your script with cron. (Be careful with the paths in the script shell)
Now, for the sudo problem... well even if you put it in a shell script, you would still need to pass your sudo password, and cron runs in the background so you won't be able to enter your password.
You could try two solutions. Change the rights on the containing folder where your files are stored (by using chmod -r 777 or chmod 755 on the folder) or move/copy your files in a directory where you have access to read and write.

Related

How can I backup mongodb database regularly, the specific time of a day

I want to backup database regularly in my linux server (Ubuntu 12.02),
I red some documents and that saying I should use linux cron, and Fortunately, I found this : https://github.com/micahwedemeyer/automongobackup/blob/master/src/automongobackup.sh
I put my configuration and save it mongobackup.sh and put it to /etc/cron.daily
It was 3 days ago, Today, I check the backup folder(/var/backups/mongodb) but the backup file does not exist.
Should I detele extension of mongobackup.sh? or something I missed?
It looks like your mongobackup.sh doesn't have proper rights to be executed.
chmod 755 /etc/cron.daily/mongobackup.sh should do the trick, but it wouldn't hurt to see what's inside of the script and results of ls -l /etc/cron.daily.
Also, you could manually add a task to root crontab (or any other user that has rights to run the script and to work with everything mentioned there):
to start editing crontab enter command crontab -u username -e
in the end of the file insert this: 0 0 * * * /bin/sh /full-path-to-mongobackup.sh >/dev/null 2>&1, press Esc, :wq, Enter - that will create a task, which will run mongobackup.sh every midnight.
And in order to answer your question about how you could run scripts in specific time of a day i would recommend you to read this article about cron and crontab.

What step am I missing in creating a cron job?

I can't seem to run cron jobs and I can't figure out why. I'm new to this so I might be making an amateur mistake.
First, I create a script and call it 'test.sh', putting it in the /usr/local/bin folder. The script contains:
#!/bin/bash
echo "This test works!"
Next, I create a file called 'randomtest' in the /etc/cron.d folder. The file contains:
00 09 * * * root /usr/local/bin/test.sh >> /var/log/test.log
I expect the cron job to run at 9:00 AM every day, but for some reason, it doesn't. I also don't get a log file as expected. I checked the permissions on the test.sh file and it's currently set to 755, which should work.
Is there something I'm doing wrong? Am I missing a crucial element? Do I need to add my 'randomtest' file to the crontab or something?
Reload the cron daemon by using /etc/init.d/crond reload.
(Even if it's already running!)
The problem is that you're messing around with the /etc/cron.d directory rather than using the crontab command.
Unless you definitely need a cron job to run as root, just add it to your own crontab using the crontab command. You can use crontab -e to edit it, but it's better to keep your own copy of your crontab (ideally under version control) and use the crontab filename version of the command to install it. This ensure that the cron daemon will be aware of the update, and that any syntax errors will be caught. It also means you don't need to run any commands as root; avoiding root commands unless they're actually necessary is always a good idea.
Note that system crontabs (those in /etc/crontab and under the /etc/cron.d directory -- though those locations are implementation details that you ideally shouldn't have to worry about) have a different syntax than user crontabs; each line has an extra field that specifies the account under which the commans is to be run.
If you need a command to run as root, you can either update a system crontab file (carefully!), or you can set up a user crontab for the root user, using the normal crontab command as you would for any user account.

cronjob entry in crontab -e vs /etc/crontab . Which one is better?

What is the difference when I put crontab entry in crontab -e (the default location is : /var/spool/cron/username ) and in /etc/crontab? I mean crond daemon will essentially execute both cron jobs. Then why there are two different ways to schedule cronjob ? Which one preferred over the other ?
The difference is that the crontab command is the interface provided by the system for users to manipulate their crontabs. The /etc/crontab file is a special case file used to implement a system-wide crontab. /var/spool/cron/crontabs/$USER (or whatever the path happens to be) is an implementation detail.
If you can schedule jobs using the crontab command, you should do so.
Manually editing the contents of /etc/crontab (a) requires root access, and (b) is more error-prone. You can mess up your system that way.
If the jobs are to be run under your own user account, there's no need to use root access.
Even if the jobs are to run as root, it probably still makes more sense to use the crontab command invoked from the root account. (For one thing, it should detect syntax errors in the file.)
Personally, I don't use crontab -e. Instead, I have a crontab file that I keep in a source control system, and I use the crontab filename form of the command to install it. That way, if I mess something up, it's easy to revert to an earlier version.
Differences :
$PATH
(On my Red Hat 7 system)
Running via /etc/crontab : $PATH is /sbin:/bin:/usr/sbin:/usr/bin
Running via crontab -e : $PATH is /usr/bin:/bin
Access
Only root can access /etc/crontab
User can access their own /var/spool/cron/user-name
Format
/etc/crontab needs an extra parameter, preceding the command, which specifies the user.
crontab -e (/var/spool/cron/user-name) obviously does not need the user name in the crontab entry.

Script runs from terminal, but not cron. What edits to this script do I need to make?

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.

shell script doesn't run fully when run as a cron job

I'm having a peculiar issue with a shell script that I have set to run every minute via crontab.
I use Pelican as a blog platform and wanted to semi-automate the way in which the site updates whenever there's a new post. To do this, I've created a script to look for a file called respawn in the same directory as the content (it syncs via Dropbox so I simply create the file there which syncs to the server).
The script is written so that if the file respawn exists then it rebuilds the blog and deletes it. If it's not, it exits instead.
Here's the script called publish.sh
#!/bin/bash
Respawn="/home/user/content/respawn"
if [ -f $Respawn ]
then
sudo /home/user/sb.sh;rm $Respawn
else
exit 0
fi
exit 0
Here's the crontab for the shell script
* * * * * /home/user/publish.sh
And finally, here's the contents of sb.sh
make html -C /var/www/site/
Now, if I run the script via SSH and respawn exists, it works perfectly. However, if I let the cron do it then it doesn't run the shell script but it still deletes the respawn file.
I have one other cron job that runs every 4 hours that simply runs sb.sh which works perfectly (in case I forget to publish something).
I've tried using the user's crontab as well as adding it to root instead and I've also added the user to the sudoers file so it can be run without password intervention. Neither seem to work. Am I missing something?
It must be sudo. cron can't input the password.
Check mail for the user running the cron to confirm. Something like sudo: no tty present.
Try changing sudo /home/user/sb.sh;rm $Respawn to
/home/user/sb.sh;rm $Respawn
sudo is not necessary to run your command in this context, since it'll be invoked as root anyway.

Resources