I want a script to create a cron entry programmatically instead of requiring someone to edit it manually with `crontab -e`. For example, I have a script that checks RAM usage, and I would like it to run automatically every five minutes. Is there a safe and reliable way for the script to install that scheduled job?
4 Answers
The usual approach is to build a temporary crontab file, add the desired line, and install it with `crontab`. For example: `crontab -l > /tmp/mycron 2>/dev/null; printf '%sn' '*/5 * * * * /absolute/path/to/script' >> /tmp/mycron; crontab /tmp/mycron`. Make sure the script uses an absolute path and clean up the temporary file. If you pipe the output directly, this also works: `{ crontab -l 2>/dev/null; printf '%sn' '*/5 * * * * /absolute/path/to/script'; } | crontab -`. Be careful to avoid adding the same line every time the installer runs.
For one-shot scheduling from a running program, `at` may be more appropriate than modifying a recurring crontab. Also consider the standard cron directories such as `/etc/cron.d` or the hourly and daily directories when you are installing system-wide jobs; the exact permissions and format depend on the operating system.
Be careful if the script adds its own cron entry every time it runs. Without checking first, you will create duplicates: after each execution there could be more identical jobs, causing the script to run repeatedly and multiply the problem. A setup or installation script should add the entry only if it is not already present, or replace a clearly marked block in the crontab.
If the task is simply checking RAM every five minutes, the script probably should not install its own schedule each time it runs. Install the cron entry once, or use a configuration-management tool such as Ansible. For a continuously running service, a systemd service with a timer may be a better fit because it can be managed and monitored with `systemctl`. Tools such as `sar` may also already provide the system monitoring data you need.

Using `crontab` rather than editing `/var/spool/cron` directly is preferable because it handles locking and validates the resulting syntax.