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.
Related
I'm digging along CRON and scheduling.
I setup a scheduled job to fire every minute via $crontab -e + editing the file (weirdly named "/tmp/crontab.vst6TX/crontab")
My understanding is that $crontab -e opens A crontab... and that cron.d, the daemon, picks up the crontab and APPENDS the cron job within to the (systemwide) /etc/crontab. (as per comment from crontab being saved in tmp/ in debian)
I'm watching the cron job fire every minute - yet I can't see it being added to the /etc/crontab job list... why? $crontab -l does show the job...
crontab -e and crontab -l are to edit and display (respectively) the current user's crontab file (which are physically located in /var/spool/cron/crontabs). Therefore, each user can have their own separate crontab file in that directory. So when you ran crontab -e and added a cron line, you ran crontab -l as the same user presumably, and therefore saw the line you added.
/etc/crontab is a completely different file. You are correct, it is systemwide -- notice that the cron lines in that file specify a user. The same is true for files in /etc/cron.d, the cron lines in the files will specify a user.
Oh and also, the .d suffix in cron.d does not refer to daemon. Check this post out.
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
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.
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.
I have this executable that queries a remote server for a command, executes it on the local machine and returns the stdout (and also possibly stderr) from it back to the server.
This executable runs just fine if called from the command line (as root), but I found it's failing for some commands when executed automatically by the cron job.
What are the differences in terms of environment (users, stdin, stdout, etc.) I should expect when scheduling this executable to run periodically using crontab?
Thanks!
The most important difference is that files like .bashrc etc. are not executed before cron jobs, so a lot of environment variables that you normaly have in the command line will be missing. So if your program doesn't work in the cron job, embedd it in a script that sets all the necessary environment variables.
Regarding input and output, there is obviously no user interaction for cron jobs, so the programs should not expect input (if they do, provide it from an input file or directly in the script), and any output should be redirected into a log file.
This executable runs just fine if called from the command line (as root), but I found it's failing for some commands when executed automatically by the cron job.
In cron jobs you can specify what user to run the script as, for example:
0 0 * * * www-data /usr/bin/php /var/www/foo/do_work.php
I am specifying to run 'do_work.php' as www-data everyday... This file would be located in /etc/cron.d/
Also, you should probably check the UID that cron uses for running the tasks, especially if it's a 'global' /etc/crontab job, not a user-level one. Could be that some permissions are lacking if the job is running from 'nobody' or 'cron'.
Mainly
Current working directory - you cannot guarantee what this is going to be from cron. It may be $HOME, but don't count on it
Environment variables - most that you have setup for normal logins will NOT be set, so things which require environment variables to have specific values may fail. This notably includes $PATH.
stdin / stdout / stderr will not be a tty, so some programs will behave differently because of this (stdout and err will probably be a temp file; stdin will probably be null)
But essentially you can't rely on much
User ID, group id and supplementary groups should be set as per a normal login for the owner of the cron job