Skip to main content
SysAdmin Shell Scripting Essentials

Crontab Every Four Hours — Syntax, Examples & Common Pitfalls

crontab every four hours is a cron schedule that runs a command at intervals evenly divisible by 4 (00:00, 04:00, 08:00, 12:00, 16:00, 20:00).

# Edit current user's crontab
crontab -e

# Inside editor, add line for every 4 hours on the hour:
0 */4 * * * /path/to/command

Use crontab -e to edit; the 0 in the minute field avoids running 60 times per hour. The step syntax */4 works on Vixie cron, cronie, and BSD cron.

Usage Examples

1. Standard every 4 hours on the hour

# Run a backup script at 00:00, 04:00, 08:00, 12:00, 16:00, 20:00
0 */4 * * * /usr/local/bin/backup.sh

The 0 in the minute field ensures execution only once per hour. Without it (e.g., * */4 * * *), the job would run every minute during those hours (60 times per cycle). Always specify minute = 0 for discrete hourly intervals.

2. Every 4 hours starting 4 hours after boot (no fixed clock)

# Add this to /etc/cron.d/myjobs or a systemd timer
@reboot sleep 4h && /path/to/command

# Then add a while-loop script that reschedules itself every 4h
#!/bin/bash
while true; do
    /path/to/command
    sleep 4h
done
# Launch the script at reboot via @reboot

This approach decouples execution from the wall clock. It is useful for unstable environments (e.g., laptops that shutdown frequently). Use @reboot or a systemd OnBootSec=4h timer to avoid schedule creep across reboots.

See also  Vim Redo Command: Ctrl+R, :redo, and Undo History Navigation

3. Exclude midnight-to-7am window with every 4 hours starting at 4pm

# Run at 16:00, 20:00, 00:00, 04:00, but skip complete range 00:00–07:00
# → implement with two cron lines:
0 16,20 * * * /path/to/cmd   # 4pm and 8pm
0 8,12 * * * /path/to/cmd    # 8am and 12pm (next day start)
# Or combine: 0 8,12,16,20 * * *

Native cron cannot easily blacklist a time window on a repeating divisor. The safest method is to enumerate allowed hours explicitly. For a single expression, cloud schedulers or a wrapper script checking $(date +%H) inside the command is more maintainable.

Frequently Asked Questions

What is the difference between `0 */4 * * *` and `0 0,4,8,12,16,20 * * *` for a cron job every four hours?

Answer: `*/4` steps the hour from 0 to 23 every four; the list runs only at explicit hours.

The step syntax `*/4` is equivalent to an explicit list starting at 0 with step 4. Some older cron implementations may not support steps; then use comma-separated hours. Verify with `crontab -l`.

# Step syntax (Vixie cron, cronie, BSD)
0 */4 * * * /usr/bin/script.sh
# Explicit list (legacy compatibility)
0 0,4,8,12,16,20 * * * /usr/bin/script.sh

When should I use the `-e` flag over editing `/etc/crontab` for a user’s “every four hours” schedule?

Answer: Use `crontab -e` for per-user jobs without root.

User crontabs are stored in `/var/spool/cron/` and run as that user. `/etc/crontab` requires specifying the user (e.g., `root`) and respects `/etc/cron.allow/deny`. For personal non-root jobs, always use `crontab -e`.

# User crontab (non-root)
crontab -e
# Add line:
0 */4 * * * /home/user/script.sh

# System crontab (requires root)
echo "0 */4 * * * root /usr/local/bin/script.sh" >> /etc/crontab

How do I fix “bad hour” error when setting `0 0-23/4 * * *` in crontab?

Answer: Verify hour values are 0–23, no extra spaces or non-numeric characters.

See also  Get-CimInstance: PowerShell Cmdlet Syntax, Flags, and Examples

The error “bad hour” typically arises from an invalid range, stray characters, or unsupported step syntax. Common fixes:

# Check for trailing spaces or tabs
crontab -l | cat -A   # Shows $ at line ends, ^I for tabs

# Explicit list (guaranteed to work)
0 0,4,8,12,16,20 * * * /path/command

# Step syntax (if supported)
0 */4 * * * /path/command

After editing, validate with `crontab -l`.

Does the `*/4` hour syntax work on all Unix-like platforms (Linux, macOS, FreeBSD)?

Answer: Yes, Linux (Vixie/cronie), macOS (bsd cron), and FreeBSD support step syntax.

POSIX does not mandate step syntax; it is a common extension. Test with a single command:

# Check cron version
cron -V 2>/dev/null | head -1     # Vixie cron
/usr/sbin/cron -V 2>/dev/null     # cronie

# For BusyBox or older systems, avoid steps:
0 0,4,8,12,16,20 * * * /path/command

Docker images using Alpine (BusyBox crond) require explicit listing.

What is the fastest way to set a crontab entry every four hours using a non-interactive one-liner?

Answer: Pipe the existing crontab and new entry to `crontab -`: `(crontab -l 2>/dev/null; echo “0 */4 * * * /cmd”) | crontab -`.

This method appends without interactive editing, preserving existing entries. Use double quotes for literal asterisks:

# Append "every four hours" to current user crontab
(crontab -l 2>/dev/null; echo "0 */4 * * * /usr/local/bin/script.sh") | crontab -

# Overwrite entire crontab (destroy existing) - faster but dangerous:
echo "0 */4 * * * /cmd" | crontab -

For root system-wide, use `echo` into `/etc/cron.d/` or append to `/etc/crontab`.