Introduction
Linux administrators schedule work in several ways. The at command schedules one-time jobs, cron schedules recurring jobs from simple time fields, and systemd timers schedule systemd services with systemd's dependency and logging model.
In this lab, you will create one command script and schedule it three ways. You will inspect the scheduler services, queue a one-time at job, configure a cron drop-in file, create a systemd service and timer pair, and manually test the service behind the timer.
Inspect Schedulers and Create a Job Script
In this step, you will confirm that the scheduler services are running and create one small script that all scheduled jobs will call.
Move into the project directory.
cd /home/labex/project
Check the one-time job daemon and the cron daemon. systemctl is-active prints active when a service is currently running.
systemctl is-active atd crond
List existing systemd timers. The output shows the next run time, the timer unit, and the service unit it activates.
systemctl list-timers --all --no-pager | sed -n '1,10p'
Create a script that appends a timestamped line to a log file. The first argument, $1, becomes the label that identifies which scheduler ran the script.
cat > /home/labex/project/scheduled-note.sh <<'EOF'
#!/bin/bash
echo "$(date '+%F %T') $1" >> /home/labex/project/schedule-events.log
EOF
Make the script executable.
chmod 755 /home/labex/project/scheduled-note.sh
Run the script manually once.
/home/labex/project/scheduled-note.sh manual-run
tail -n 1 /home/labex/project/schedule-events.log
The log line should end with manual-run.
Queue a One-Time at Job
In this step, you will schedule a one-time job with at. This is useful for work that should happen once at a future time, such as a temporary maintenance task.
Queue the script to run two hours from now. The command to run is piped into at.
echo "/home/labex/project/scheduled-note.sh at-job" | at now + 2 hours
List the queued jobs.
atq
Save the job id from the first atq line. The job id is the first field in the output.
job_id="$(atq | awk 'NR==1 {print $1}')"
echo "$job_id" > /home/labex/project/at-job.id
cat /home/labex/project/at-job.id
Inspect the queued job content. at -c prints the generated job script; the final lines should include the command you queued.
at -c "$job_id" | tail -n 12
Configure a cron Drop-In File
In this step, you will configure a recurring cron job with a file in /etc/cron.d. Files in this directory include a user field, so the system knows which account should run the command.
Create a cron file that runs the script every minute as the labex user. The PATH line gives cron a predictable command search path.
sudo tee /etc/cron.d/rhcsa-schedule-demo >/dev/null <<'EOF'
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
* * * * * labex /home/labex/project/scheduled-note.sh cron-job
EOF
Set the file mode to 644. Cron files must be readable and should not be writable by ordinary users.
sudo chmod 644 /etc/cron.d/rhcsa-schedule-demo
Reload crond so it notices the file immediately.
sudo systemctl reload crond
Inspect the file you created.
sudo cat /etc/cron.d/rhcsa-schedule-demo
The schedule fields * * * * * mean every minute.
Create a systemd Service and Timer
In this step, you will create a systemd service and a timer that activates it. A timer does not run a command directly; it starts a service unit.
System services should execute commands from system executable paths, not from a user's working directory. Install a copy of your script under /usr/local/bin.
sudo install -m 755 /home/labex/project/scheduled-note.sh /usr/local/bin/rhcsa-scheduled-note
sudo restorecon /usr/local/bin/rhcsa-scheduled-note 2>/dev/null || true
ls -l /usr/local/bin/rhcsa-scheduled-note
Create the service unit. Type=oneshot is appropriate for a command that runs and exits.
sudo tee /etc/systemd/system/rhcsa-schedule-demo.service >/dev/null <<'EOF'
[Unit]
Description=Write RHCSA schedule demo entry
[Service]
Type=oneshot
User=labex
ExecStart=/usr/local/bin/rhcsa-scheduled-note timer-job
EOF
Create the timer unit. OnBootSec=2min schedules a first run after boot, and OnUnitActiveSec=5min schedules later runs relative to the previous activation.
sudo tee /etc/systemd/system/rhcsa-schedule-demo.timer >/dev/null <<'EOF'
[Unit]
Description=Run RHCSA schedule demo periodically
[Timer]
OnBootSec=2min
OnUnitActiveSec=5min
Unit=rhcsa-schedule-demo.service
[Install]
WantedBy=timers.target
EOF
Reload systemd, enable the timer for boot, and then start it now. Splitting enable and start makes it clear which command makes the timer persistent and which command activates it immediately.
sudo systemctl daemon-reload
sudo systemctl enable rhcsa-schedule-demo.timer
sudo systemctl start rhcsa-schedule-demo.timer
Inspect the timer.
systemctl list-timers rhcsa-schedule-demo.timer --all --no-pager
The timer should appear in the list, and it should activate rhcsa-schedule-demo.service.
Test the Timer Service and Remove the at Job
In this step, you will manually start the service used by the timer. This verifies the command immediately without waiting for the next scheduled timer activation. You will also remove the queued at job because it was only for practice.
Start the service manually.
sudo systemctl start rhcsa-schedule-demo.service
Inspect the log.
tail -n 5 /home/labex/project/schedule-events.log
One line should end with timer-job.
Remove the queued at job by using the job id saved earlier.
job_id="$(cat /home/labex/project/at-job.id)"
atrm "$job_id"
Confirm the job is no longer queued.
atq
Summary
You practiced three scheduling methods. You inspected atd, crond, and systemd timers, created a reusable scheduled command script, queued and inspected a one-time at job, configured a recurring cron drop-in file, installed a service-safe command under /usr/local/bin, created a systemd service and timer pair, manually tested the timer service, and removed the temporary at job.



