Without understanding automation and scheduling, a system administrator would have to wake up at 3 AM every day to run backup scripts or manually log in every hour to check if a report has finished. This is exhausting, error-prone, and impossible at scale. The Linux Professional Institute Certification Level 2 (LPIC-2) exam tests your ability to automate these tasks using cron, at, and systemd timers, which are the tools that let a computer perform work on a schedule without human intervention.
Jump to a section
A simple way to picture Automation and Scheduling (cron, at, systemd timers)
The restaurant kitchen manager is responsible for ensuring the right dishes are prepared at the right times, without constant manual instruction. They don't stand over every chef and tell them to start chopping vegetables or to put a steak on the grill.
Instead, they set up systems. The manager might write a daily prep list (the "cron" equivalent) that tells the breakfast chef to start poaching eggs at 6:30 AM every Monday, and the pastry chef to bake croissants at 5:00 AM every day. This is a recurring schedule, running at fixed times.
Sometimes, a VIP guest calls and wants a special meal prepared in three hours. The manager can't add that to the daily prep list because it's a one-off. Instead, they write a single note (the "at" equivalent) that says: "At 2:00 PM, prepare the lobster thermidor for table seven."
Finally, the manager might set up a smart timer on the oven (the "systemd timer" equivalent) that not only turns the oven on at 4:00 AM, but also checks that the gas line is connected and the internal temperature reaches 200 degrees before it allows the chefs to start baking. This timer can also react dynamically—if the oven fails, it can trigger an alert and a backup procedure. It's a more modern, resilient system than a simple alarm clock. The manager uses all three methods to orchestrate a smooth service, ensuring every dish arrives at the right time without chaos.
Automation and scheduling are the techniques that let you tell your Linux system to perform tasks at specific times or when certain conditions are met, without you needing to be logged in. Think of it as setting a digital calendar for your computer. The three main tools for this are cron, at, and systemd timers.
First, let's talk about 'cron'. Cron is a daemon—a background process that runs constantly—that reads configuration files called 'crontabs'. A crontab, short for 'cron table', is a file that lists jobs (commands to run) and their schedule. The schedule is defined by five time-and-date fields: minute (0-59), hour (0-23), day of month (1-31), month (1-12), and day of week (0-7, where 0 and 7 are Sunday). For example, '30 2 * * 1' means 'run every Monday at 2:30 AM'. The asterisks mean 'every'. So, you could have a cron job that backs up a database every day at midnight, or a job that sends a log report every Friday at 5 PM. Users can manage their own crontabs with the 'crontab -e' command. The system also has system-wide crontabs stored in directories like /etc/cron.hourly/, /etc/cron.daily/, etc.
Now, what about 'at'? The 'at' command is for one-time scheduled tasks. If you need to run a command at a specific time in the future, just once, you use 'at'. For instance, you might say 'at 3:00 PM' and then type the command you want to run. The system will execute it at exactly 3:00 PM, and then forget about it. This is ideal for deferred maintenance, like scheduling a reboot for 2 AM during a low-usage period. The 'atq' command lists pending 'at' jobs, and 'atrm' cancels them. The 'at' daemon (atd) must be running for this to work.
Finally, there are 'systemd timers'. systemd is the modern init system and service manager used by most Linux distributions today. A systemd timer is a unit file that controls when a corresponding service unit (a command or script) should run. Timers are more powerful than cron. They can run jobs at specific calendar times (like cron), but they can also run jobs relative to system events, such as '15 minutes after boot' or 'one hour after the last job finished'. Timers also have built-in features like randomised delays (to avoid load spikes from many jobs starting at once), persistent timers that catch up on missed runs after a system outage, and accurate monotonic timers for real-time latency. You enable a timer with 'systemctl enable timerName.timer' and start it with 'systemctl start timerName.timer'.
Why do we have three different tools? Each solves a different problem. Cron is excellent for predictable, recurring tasks like nightly maintenance. 'at' is perfect for one-off tasks that you don't want to repeat. systemd timers are the most modern and flexible, offering finer control and integration with the systemd ecosystem (like dependency management and logging). On the LPIC-2 exam, you must understand the syntax of each, how to create and manage them, and the common pitfalls such as environment variables (cron jobs run with a minimal shell environment, not your user's full profile) and output handling (by default, cron mails any output to the job owner).
Let's look at a concrete example of each. For a cron job, you'd edit your crontab: 'crontab -e'. You then add a line: '0 3 * * 1 /usr/bin/backup-script.sh'. This runs backup-script.sh every Monday at 3:00 AM. For an 'at' job, you'd type 'at 5:00 PM' then press Enter, type 'shutdown -h now' and press Ctrl+D. For a systemd timer, you create two files in /etc/systemd/system/: a service file (e.g., mybackup.service) and a timer file (e.g., mybackup.timer). The timer file contains the schedule, like 'OnCalendar=daily' or 'OnBootSec=10min'. You then enable and start the timer.
Common gotchas include remembering that the cron daemon must be running ('systemctl status cron' or 'ps aux | grep cron'), that 'at' jobs are stored in /var/spool/at/, and that systemd timers are separate unit files. Also, the environment for cron jobs is sparse—PATH is often just /usr/bin:/bin, so you should always use full paths to commands.
To manage these tools, you use standard Linux commands: 'crontab' (to edit, list, remove user crontabs), 'at', 'atq', 'atrm', 'systemctl', 'systemd-run' (to run a command as a transient timer). Understanding the logging for each is also crucial for exam troubleshooting. Cron logs are typically in /var/log/syslog or /var/log/cron. 'at' logs are often in /var/log/daemon.log. systemd timers log through the journal, accessible with 'journalctl -u mybackup.timer'. For the LPIC-2 exam, you need to be able to read and interpret these logs to diagnose why a job didn't run.
In summary, automation and scheduling are essential for efficient system administration. They free you from manual, repetitive tasks and ensure reliability. As you prepare for the LPIC-2 exam, focus on the syntax of each tool, the management commands, the environment differences, and the debugging techniques.
Creating a User Crontab
Run 'crontab -e' as the user. This opens the user's crontab file in the default text editor (e.g., vi or nano). Add a line with the schedule and command, such as '0 4 * * * /usr/bin/backup.sh'. Save and exit. The cron daemon will read the new crontab and execute the job accordingly.
Verifying the Crontab is Active
Run 'crontab -l' to list the current crontab entries. This confirms your job was saved. You can also check the cron daemon status with 'systemctl status cron' to ensure it is running, as it must be active for jobs to execute.
Scheduling a One-Time Job with 'at'
Type 'at 3:30 PM', press Enter. Then type the command you want to run, e.g., 'shutdown -h now'. Press Ctrl+D to save. The system confirms the job with a job number. Use 'atq' to see the pending job. Use 'atrm jobnumber' to cancel it.
Creating a Systemd Timer and Service Unit
Create two files in /etc/systemd/system/: a service file (e.g., myjob.service) containing the command to run, and a timer file (e.g., myjob.timer) containing the schedule directive, e.g., 'OnCalendar=*-*-* 06:00:00'. Then run 'systemctl daemon-reload', 'systemctl enable myjob.timer', 'systemctl start myjob.timer'. The timer is now active.
Monitoring Jobs and Debugging Failures
For cron, check /var/log/syslog for cron entries. For 'at', check /var/log/daemon.log. For systemd timers, use 'journalctl -u myjob.timer' and 'journalctl -u myjob.service'. Look for 'FAILED' status or error messages. Common fixes involve checking permissions, command paths, and environment variables.
An IT professional, often called a system administrator or site reliability engineer, uses automation and scheduling to keep systems running smoothly without manual oversight. Consider a typical scenario at a mid-sized e-commerce company. The company has an online store, a customer database, and a server that processes orders. The IT team needs to perform several recurring tasks.
First, every night at 2:00 AM, the database must be backed up. The system administrator writes a cron job: '0 2 * * * /usr/local/bin/backup-db.sh'. This script connects to the database, dumps the data to a compressed file, and copies it to a remote storage location. Using cron ensures this happens every night reliably, even if the admin is asleep or on holiday.
Second, the company often releases software updates. The admin might schedule a one-off system reboot for next Tuesday at 4:00 AM using the 'at' command. They run 'at 4:00 AM Tue', then type 'shutdown -r now'. This ensures the reboot happens during off-peak hours and the admin doesn't have to remember to do it manually.
Third, the company has a monitoring script that checks if the main web server is running. If the server crashes, it needs to be restarted immediately, but only after the server has been down for at least 30 seconds to avoid a restart loop. The admin creates a systemd timer that runs a health check script every minute. The timer is configured with 'OnCalendar=*:0/1' and the associated service script checks the server, and if it's down, waits 30 seconds and then restarts it. The timer also has 'RandomizedDelaySec=5' to avoid all cron jobs hitting the system at the exact same second.
Fourth, the company has a compliance requirement to rotate log files every week. The admin adds a cron job that runs a log rotation script every Sunday at 3:00 AM. The script compresses old logs and deletes logs older than 30 days.
Finally, the admin needs to test a new backup script without waiting for the nightly cron job. They use 'systemd-run' to create a transient timer: 'systemd-run --on-active=10 /usr/local/bin/test-backup.sh'. This runs the test script after 10 seconds, without creating a permanent timer file.
The admin also regularly monitors the logs: they check /var/log/syslog for cron job failures, use 'journalctl -u backupdb.service' for systemd timer service logs, and 'atq' to see pending 'at' jobs. When a job fails, they check the environment. For example, a cron job might fail because the PATH environment variable doesn't include the directory where a command lives. The admin fixes this by specifying the full path in the script or by setting PATH in the crontab file.
In this real-world context, the IT professional doesn't just set and forget. They also manage user permissions (who can use 'at' or 'cron'), ensure the daemons are running ('systemctl status cron atd'), and handle exceptions like daylight saving time changes (cron usually handles this fine, but 'at' jobs scheduled during a skipped hour can cause issues). This practical, hands-on knowledge is exactly what the LPIC-2 exam evaluates. You must be able to create, manage, and troubleshoot these scheduling tools in real server environments.
The LPIC-2 exam objective 200.4, 'Automation and Scheduling', tests your ability to configure and manage the three main scheduling tools on Linux. The exam expects you to be comfortable with the syntax, management commands, and common pitfalls. Here is exactly what you need to focus on.
First, the exam tests your knowledge of cron syntax. You must be able to read and write crontab entries. The format is: minute, hour, day of month, month, day of week. For example, '15 3 * * 1-5' means 'at 3:15 AM, Monday through Friday'. The exam loves to give you a crontab line and ask what time it runs, or give you a time description and ask for the correct crontab line. They also test special strings like '@reboot' (runs once at boot), '@daily', '@hourly', '@weekly', '@monthly'. You must know that '@reboot' does not use the standard five-field syntax.
Second, the exam tests the management of cron: how to create a user crontab ('crontab -e'), how to list it ('crontab -l'), and how to remove it ('crontab -r'). They also test system-wide cron directories: /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/. The files in these directories are run by the anacron or cron daemon, and the scripts must be executable. The exam also covers the /etc/crontab file (system crontab) which includes an extra field for the username to run the job as, e.g., '0 2 * * * root backup-script'.
Third, the exam tests the 'at' command. You need to know how to schedule a one-time job: 'at 5:00 PM', then type the command. You must know 'atq' to list jobs, 'atrm' to remove a job by job number. They also test 'batch' (a variant that runs a job when the system load is low) and the configuration files /etc/at.allow and /etc/at.deny which control user access. The exam often includes a scenario where a user cannot use 'at', and you must diagnose that they are listed in /etc/at.deny.
Fourth, the exam tests systemd timers. This is a newer topic and appears frequently. You must understand the structure of a timer unit file. Key directives: 'OnCalendar' (for calendar-based, like cron), 'OnBootSec', 'OnUnitActiveSec', 'OnStartupSec' (for relative timers), 'RandomizedDelaySec', 'Persistent' (if true, the timer will trigger immediately after a missed run, e.g., after a system reboot). You also create a matching service unit file. You manage timers with 'systemctl enable timerName.timer', 'systemctl start timerName.timer', 'systemctl status timerName.timer'. You list timers with 'systemctl list-timers'.
Common exam traps include:
Confusing the five-field cron syntax with the systemd calendar event syntax (systemd uses 'Mon *-*-* 02:00:00' instead of '0 2 * * 1').
Forgetting that cron jobs run with a limited environment (no PATH, no USER, etc.). The exam may ask why a command works in a shell but fails in cron—the answer is often the missing PATH.
Mixing up 'crontab -e' (edits user crontab) with editing /etc/crontab directly (system crontab). The system crontab requires a username field.
Not understanding that 'at' jobs are stored in /var/spool/at/ and can be listed with 'atq'.
Overlooking the need for the 'at' daemon ('atd') to be running.
Confusing 'OnBootSec' (time after boot) with 'OnStartupSec' (time after the systemd process started, essentially the same for most purposes but subtle differences).
Not knowing that 'Persistent=true' in a systemd timer means it will run missed jobs after the next boot (if the system was off during the scheduled time).
The exam also tests troubleshooting. You might be given a log file and asked to identify why a command didn't run. Look for missing permissions, wrong syntax, or the daemon not running. They also test output handling: by default, cron mails job output to the user's local mailbox. You can suppress this with '>/dev/null 2>&1'. \ - Memorise these exact concepts:
Crontab five-field format: minute hour dom mon dow.
Special cron strings: @reboot, @daily, @hourly, @weekly, @monthly.
'at' commands: at, atq, atrm.
systemd timer directives: OnCalendar, OnBootSec, Persistent, RandomizedDelaySec.
systemd timer management: systemctl enable/start/status/list-timers.
Log locations: /var/log/syslog (cron), /var/log/daemon.log (at), journalctl (systemd).
Access control files: /etc/cron.allow, /etc/cron.deny, /etc/at.allow, /etc/at.deny.
A cron job uses a five-field schedule: minute (0-59), hour (0-23), day of month (1-31), month (1-12), day of week (0-7).
The 'at' command schedules a one-time job and uses 'atq' to list jobs and 'atrm' to remove them.
Systemd timers use directives like 'OnCalendar' for calendar-based scheduling and 'OnBootSec' for relative scheduling after boot.
Cron jobs run with a sparse environment; always use absolute paths to commands to avoid failures.
You control user access to cron and at with files like /etc/cron.allow, /etc/cron.deny, /etc/at.allow, and /etc/at.deny.
Systemd timers can be persistent with 'Persistent=true', meaning they will catch up on missed runs after a system outage.
These come up on the exam all the time. Here's how to tell them apart.
cron
Uses a five-field syntax (minute, hour, day, month, weekday)
Cannot run relative to boot or system events
Does not have built-in persistent or randomised delay features
systemd timers
Uses calendar event syntax (e.g., OnCalendar=daily) or relative directives (OnBootSec=10min)
Can run relative to boots, startup, or service unit activation
Supports Persistent=true for catching up on missed runs and RandomizedDelaySec for load distribution
at
Schedules only one execution at a specific time
Commands are stored in /var/spool/at/ and can be managed with atq/atrm
Useful for one-off maintenance tasks like a reboot
cron
Schedules recurring executions based on a time pattern
Commands are stored in /var/spool/cron/crontabs and managed with crontab
Useful for daily, weekly, or monthly recurring tasks
user crontab (crontab -e)
Does not require a username field in the job line
Edited with the 'crontab -e' command
Only the owning user and root can edit it
system crontab (/etc/crontab)
Requires a username field (e.g., 'root' or 'nobody') in the job line
Edited manually as root in /etc/crontab
Available to root for system-wide jobs
cron daemon
Daemon name is often 'cron' or 'crond'
Reads crontab files continuously
Logs to /var/log/syslog or /var/log/cron
at daemon
Daemon name is 'atd'
Reads scheduled jobs from /var/spool/at/
Logs to /var/log/daemon.log
Mistake
Cron jobs run with the same environment as my shell when I log in.
Correct
Cron jobs run with a very minimal environment. PATH is often just /usr/bin:/bin, and many environment variables are not set. That is why a command that works in your terminal often fails in cron unless you use full paths.
Beginners assume that because they are the same user, the environment is identical. They don't realise that cron does not source profile files like ~/.bashrc.
Mistake
The asterisk in a crontab field means 'ignore this field'.
Correct
Asterisk means 'every possible value'. For example, '*' in the month field means 'every month', not 'ignore'. This is a crucial distinction.
People confuse the meaning because it's similar to wildcards in file names, but it's actually a placeholder for all values.
Mistake
Systemd timers are just a complicated way to do the same thing as cron.
Correct
Systemd timers are more powerful because they can run relative to system events (e.g., '15 min after boot'), have persistent run capability, support randomised delays to prevent load spikes, and integrate with service dependencies and logging via journald.
Many people come from older systems and see systemd as unnecessary complexity, so they dismiss its unique features.
Mistake
I can edit the /etc/crontab file directly with crontab -e.
Correct
The 'crontab -e' command edits your user's personal crontab. The system crontab is /etc/crontab and must be edited manually with a text editor as root. They have different syntax: the system crontab requires an extra field for the username.
The command 'crontab' is ambiguous to beginners—they think it refers to the file, not the command. They also miss the difference in syntax.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
Use the command 'crontab -e' as your user. This opens your personal crontab in the default text editor. Never edit the files in /var/spool/cron/crontabs directly.
Common reasons: the cron daemon is not running, the command path is incorrect (use absolute paths), there is a syntax error in your crontab line, or the script lacks execute permissions.
Use a crontab line like '* * * * * /path/to/command'. The asterisk in each field means 'every', so the job runs every minute of every hour of every day.
Cron is older and simpler, using a five-field syntax for recurring jobs. Systemd timers are newer, more flexible, and can run based on system events (like boot), with features like randomised delays and persistent run after system downtime.
First, use 'atq' to list pending jobs and find the job number. Then use 'atrm jobnumber' to cancel it. For example, 'atrm 5' cancels job number 5.
Yes, you can use 'OnCalendar=Mon,Thu *-*-* *:00:00' in the timer unit file. This runs the job at midnight on every Monday and Thursday. You can also use more complex calendar expressions.
You've finished Automation and Scheduling (cron, at, systemd timers). Continue through the LPIC-2 study guide to build a complete picture of the exam.
Done with this chapter?