Correct way to edit cron jobs?

thomas-hn

Member
Oct 26, 2021
42
10
13
44
Hi,

what is the correct way to edit cron jobs on the Proxmox host?
In the file "/etc/crontab" I can see some default content:
Code:
root@pve:~# cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

But if I execute "crontab -e" there is only:
Code:
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

So what is the correct way to add own cron jobs?
And do I need to restart cron at the end? For example, via:
Bash:
/etc/init.d/cron restart

Thanks a lot in advance,

Thomas
 
Last edited:
I'd go with crontab -e. You don't need to restart cron afterwards [0].

Thanks for your clarification.
However, what I still don't understand is, why I see some jobs in "/etc/crontab" which are not shown when running "crontab -e".
 
However, what I still don't understand is, why I see some jobs in "/etc/crontab" which are not shown when running "crontab -e".


/etc/crontab is the system-wide crontab, whereas crontab -e alters the crontab of the user currently running the command. They will be stored in /var/spool/cron/crontabs/<username>.

One benefit of using crontab -e to edit is that the command will validate the syntax of the file before it is saved.
 
So from my experience when I run crontab -e it opens up nano to a tmp file /tmp/crontab.1xfrmX/crontab *

When I exit it says
Bash:
:~# crontab -e
crontab: installing new crontab
But the cron never runs. If I run crontab -e again It opens nano to another tmp file /tmp/crontab.RWLxDc/crontab but it has the previous edits there. when I save it I get the same installing new crontab message.
 
Check the cron log in /var/log.
I do not see a cron log in /var/log plus I know that it isn't running specifically because it's a scrutiny update & with the cron jobs set the data for all my Proxmox machines never updated, but if I run it manually it does.

I ended up using /etc/systemd/system/scrutiny-collector.service instead & it now runs fine.
Just for a list in case anyone is having the same problem, here's my commands, the times I created are specific to the scrutiny program so I won't share them, but it should get you to where you need to create a cron job

Bash:
### Create the service to run the binary/script
nano /etc/systemd/system/scrutiny-collector.service
### Create the timer to execute the service
nano /etc/systemd/system/scrutiny-collector.timer
### Refresh the daemon (May not be necessary)
systemctl daemon-reload
### Enable & start the Cron schedule
systemctl enable scrutiny-collector.timer
systemctl start scrutiny-collector.timer
### To check that it's running
systemctl list-timers --all
 
So from my experience when I run crontab -e it opens up nano to a tmp file /tmp/crontab.1xfrmX/crontab *

When I exit it says
Bash:
:~# crontab -e
crontab: installing new crontab
But the cron never runs. If I run crontab -e again It opens nano to another tmp file /tmp/crontab.RWLxDc/crontab but it has the previous edits there. when I save it I get the same installing new crontab message.
This is normal. It puts the current setup in a temp file for editing.

But really, on Debian-based systems, the easiest way to run something once per hour/day/week/month is to put a normal bash script into /etc/cron.{hourly, weekly, monthly}. That is how the log rotation and a number of other things do it.

I do not see a cron log in /var/log plus I know that it isn't running specifically because it's a scrutiny update & with the cron jobs set the data for all my Proxmox machines never updated, but if I run it manually it does.
That does not mean the cron job did not run. It generally means that the job failed for some reason. Wrong path, didn't set some environment variable the command needs, you ran the job as the wrong user, something like that. Remember that cron does not run with the same environment as your normal login, it is reduced for security reasons.

If you look in the journal (journalctl -b) around the time the job was supposed to run you might learn why it failed.
 
I added cron job by running crontab -e

So it looks like this:
Code:
# m h  dom mon dow   command

*/10 * * * * /root/check_frigate.sh


In addition
A've added echo messages to my script (yes I know it's ugly but for now I need quiick fix for this)
Code:
#!/bin/sh

if ! check_for_running > /dev/null 2>&1 ; then
        echo Restarting frigate;
        /usr/sbin/pct stop 105
        sleep 30
        /usr/sbin/pct start 105
fi;

And PVE send me messages (to telegram) only if my script have output (in this case only on problems)
So. this is ugly fix, but it's works and a receive notifications if this fix restarts my container

FYI: check $PATH it's better way to set $PATH in script (for example the pct command may not be found when running from the cron
or it's best for safety way: use full path like /usr/sbin/pct