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

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.

Related

How to setup cron job for each user

I want to setup crontab to run same jobs for every user on linux, is there any way just to specify the job and it will run for every user ?
Thanks
One option is to add your scripts to root/system crontab like,
either copy your scripts to
/etc/cron.daily/
/etc/cron.hourly/
/etc/cron.monthly/
/etc/cron.weekly/
or
sudo crontab -e
and then add new entry for your script.
And the problem with this option is all commands in script run with administrative privileges (i.e. they are generally run using sudo).
Any user can execute "crontab -e" (without sudo) and put your commands, obviously the user must have permissions to execute commands.
I believe /etc/crontab is global, you can add jobs to run for all users to that file.
What I am unsure about is whether you need to restart the cron service for the changes to take affect

What facility does system crontab provide that user crontab for root cannot?

I will expand my question here:
What is the need of a system crontab when every user including root has its own crontab? The existence of the system crontab seems to duplicate functionality. Is the system crontab more of an artifact of the history of the cron system?
System crontab is a great way for distro maintainers and app packagers to include cron jobs that don't pollute the user crontab space.
The system crontab files can specify a user to run as, so not everything in the system crontab has to run as root.
Non-login-users don't have crontabs, so the only place to put non-login-user tasks is in the system crontab.
Generally, you would put local/custom stuff in the root (or appropriate user) crontab, while prepackaged stuff that you don't directly maintain lives in the system crontab.
Really, it's just a matter of organization

How to handle crontab events on a gentoo Linux system?

I have a gentoo Linux system and a strange behavior of crontab. As root user, and as I understand the documentation, the command
crontab -l
lists all crontab jobs defined for the current user, root (There are no cronjobs defined for any other used). All listed cronjobs are also defined in the file /etc/cronjob.
However, there are two more crontab files located in /etc/cron.d, which define a cronjob each:
/etc/cron.d/testcron1
/etc/cron.d/testcron2
Although not listed with crontab -l, the cronjob defined in the file /etc/cron.d/testcron1 is executed. The other cronjob defined in the file /etc/cron.d/testcron2 is NOT executed.
This all does not make sense, so I have two questions:
Why does crontab -l list not all cronjobs?
Must the cronjobs in /etc/cron.d be registered somewhere, or is a restart of a daemon/service required? Why is the one started, and not the other one (the executable works fine, though).
The command crontab is used to maintain/manage crontab files for individual users. These files are usually located in /var/spool/cron/crontabs.
If crontab -l dose not show any cron jobs then this user currently has no individual cron jobs. This dose not mean that there are no cron jobs in /etc/cron* taht will run with the privileges of this user. crontab will not operate on the files in /etc/cron*. It is a tool for only managing individual (per user) cron jobs held in /var/spool/cron/crontabs.
Now lets see how the different cron jobs get executed.
Form the manpage of the cron daemon we can read:
cron searches its spool area (/var/spool/cron/crontabs) for crontab files (which are named after accounts in /etc/passwd); ...
cron also reads /etc/crontab, which is in a slightly different format (see crontab(5)).
as well as:
Additionally, in Debian, cron reads the files in the /etc/cron.d directory. cron treats the files in /etc/cron.d as in the same way as the /etc/crontab file...
(I think this applies to gentoo as well...)
About restarting we can read:
cron then wakes up every minute, examining all stored crontabs, checking each command to see if it should be run in the current minute...
Additionally, cron checks each minute to see if its spool directory's modtime (or the modtime on the /etc/crontab file) has changed, and if it has, cron will then examine the modtime on all crontabs files and reload those which have changed. Thus cron need not be restarted whenever a crontab file is modified. Note
that the crontab(1) command updates the modtime of the spool directory whenever it changes a crontab.
So the crontab command is for user specific corn jobs while the files in /etc/cron* are more for system cron jobs.
No manual triggering is needed to activate a new cron job.

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.

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.

Resources