DEV Community

Janak Shrestha
Janak Shrestha

Posted on

Create a Cron Job

The Nautilus system admins team has prepared scripts to automate several day-to-day tasks. They want them to be deployed on all app servers in Stratos DC on a set schedule. Before that they need to test similar functionality with a sample cron job. Therefore, perform the steps below:

a. Install cronie package on all Nautilus app servers and start crond service.

b. Add a cron */5 * * * * echo hello > /tmp/cron_text for root user.


Step 1: Understanding Cron and Cronie

What is Cron?

Cron is a time-based job scheduler in Unix-like operating systems. It allows users to schedule jobs (commands or scripts) to run automatically at specified times, dates, or intervals.

What is Cronie?

Cronie is a fork of the original cron daemon (vixie-cron) and is the default cron implementation in:

  • RHEL/CentOS 7+ (including CentOS Stream)
  • Fedora
  • Many other enterprise Linux distributions

Key components of cronie:

  • crond: The main daemon/service that runs cron jobs
  • crontab: The command used to manage cron jobs
  • cronie-anacron: For running jobs that were missed due to system downtime

Step 2: Installing Cronie on Multiple Servers

Interactive Method (Single Server)

Connect to each server and install cronie:

# Connect to the server
ssh tony@stapp01
# Enter password: Ir0nM@n

# Switch to root
sudo su -

# Install cronie
yum install -y cronie

# Output:
# Dependencies resolved.
# Installing:
#  cronie                      x86_64      1.5.7-16.el9
# Installing dependencies:
#  cronie-anacron              x86_64      1.5.7-16.el9
#  crontabs                    noarch      1.11-26.20190603git.el9
# Complete!
Enter fullscreen mode Exit fullscreen mode

One-Line Command (Remote Execution)

For quick deployment across multiple servers:

# For stapp01
echo 'Ir0nM@n' | ssh tony@stapp01 "sudo -S yum install -y cronie"

# For stapp02
echo 'Am3ric@' | ssh steve@stapp02 "sudo -S yum install -y cronie"

# For stapp03
echo 'BigGr33n' | ssh banner@stapp03 "sudo -S yum install -y cronie"
Enter fullscreen mode Exit fullscreen mode

Using Heredoc (Most Reliable)

For complex installations requiring multiple commands:

ssh tony@stapp01 << 'EOF'
echo 'Ir0nM@n' | sudo -S bash -c '
echo "Installing cronie..."
yum install -y cronie
echo "✓ Cronie installed successfully"
'
EOF
Enter fullscreen mode Exit fullscreen mode

Step 3: Starting and Enabling the Crond Service

After installation, you must start the crond service and ensure it starts automatically on system boot.

Service Management Commands

# Start the crond service
systemctl start crond

# Enable service to start on boot
systemctl enable crond

# Check service status
systemctl status crond

# Verify service is active
systemctl is-active crond
systemctl is-enabled crond
Enter fullscreen mode Exit fullscreen mode

Output Example:

[root@stapp01 ~]# systemctl start crond
[root@stapp01 ~]# systemctl enable crond
Created symlink /etc/systemd/system/multi-user.target.wants/crond.service → /usr/lib/systemd/system/crond.service.

[root@stapp01 ~]# systemctl status crond
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; preset: enabled)
   Active: active (running) since Mon 2026-08-31 09:57:34 UTC; 29s ago
 Main PID: 5138 (crond)
    Tasks: 1 (limit: 404712)
   Memory: 988.0K
      CPU: 3ms
Enter fullscreen mode Exit fullscreen mode

One-Line Deployment (All Servers)

# For each server
echo 'Ir0nM@n' | ssh tony@stapp01 "sudo -S bash -c 'systemctl start crond && systemctl enable crond && systemctl status crond | grep -E \"Active|Loaded\"'"
Enter fullscreen mode Exit fullscreen mode

Step 4: Understanding Cron Job Syntax

Before adding a cron job, let's understand the syntax:

* * * * * command_to_execute
│ │ │ │ │
│ │ │ │ └─── Day of week (0-7) (0 and 7 = Sunday)
│ │ │ └───── Month (1-12)
│ │ └─────── Day of month (1-31)
│ └───────── Hour (0-23)
└─────────── Minute (0-59)
Enter fullscreen mode Exit fullscreen mode

Common Time Patterns:

Pattern Meaning
* Every time unit (e.g., every minute)
*/5 Every 5 units (e.g., every 5 minutes)
30 21 * * * At 21:30 every day
0 2 * * * At 2:00 AM every day
0 0 * * 0 At midnight every Sunday
@daily Once per day (same as 0 0 * * *)
@hourly Once per hour (same as 0 * * * *)

Our Cron Job: */5 * * * * echo hello > /tmp/cron_text

This cron job:

  • Executes every 5 minutes (at minute 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55)
  • Writes "hello" to /tmp/cron_text
  • Overwrites the file each time (uses > not >>)

Step 5: Adding the Cron Job to Root's Crontab

Method 1: Using crontab -e (Interactive)

# Edit root's crontab
crontab -e

# Add this line:
*/5 * * * * echo hello > /tmp/cron_text

# Save and exit (ESC :wq in vi)
Enter fullscreen mode Exit fullscreen mode

Method 2: Using Echo with Pipe (Non-Interactive)

# Preserve existing crontab and add new job
(crontab -l 2>/dev/null; echo "*/5 * * * * echo hello > /tmp/cron_text") | crontab -
Enter fullscreen mode Exit fullscreen mode

Command breakdown:

  • crontab -l 2>/dev/null: List current crontab (suppress errors)
  • ;: Separator to run next command
  • echo "*/5 * * * * ...": The new cron job
  • | crontab -: Pipe combined output to crontab command

Method 3: Using a Temporary File

# Backup existing crontab
crontab -l > /tmp/crontab_backup 2>/dev/null

# Add new job
echo "*/5 * * * * echo hello > /tmp/cron_text" >> /tmp/crontab_backup

# Load from file
crontab /tmp/crontab_backup

# Clean up
rm /tmp/crontab_backup
Enter fullscreen mode Exit fullscreen mode

Deploying Across All Servers

# For stapp01
ssh tony@stapp01 << 'EOF'
echo 'Ir0nM@n' | sudo -S bash -c '
(crontab -l 2>/dev/null; echo "*/5 * * * * echo hello > /tmp/cron_text") | crontab -
echo "Crontab contents:"
crontab -l
'
EOF
Enter fullscreen mode Exit fullscreen mode

Step 6: Automating Deployment with a Script

Here's a complete bash script for deploying cron jobs across multiple servers:

#!/bin/bash

# Define servers with their credentials
declare -A SERVERS=(
    ["stapp01"]="tony:Ir0nM@n"
    ["stapp02"]="steve:Am3ric@"
    ["stapp03"]="banner:BigGr33n"
)

CRON_JOB="*/5 * * * * echo hello > /tmp/cron_text"

echo "========================================="
echo "Installing Cronie and Adding Cron Job"
echo "========================================="

for server in "${!SERVERS[@]}"; do
    IFS=':' read -r user pass <<< "${SERVERS[$server]}"
    echo ""
    echo "-----------------------------------------"
    echo "Processing $server (User: $user)"
    echo "-----------------------------------------"

    ssh $user@$server << EOF
echo '$pass' | sudo -S bash -c '
echo "=== Installing cronie ==="
yum install -y cronie

echo "=== Starting crond service ==="
systemctl start crond
systemctl enable crond

echo "=== Adding cron job ==="
(crontab -l 2>/dev/null; echo "$CRON_JOB") | crontab -

echo "=== Current crontab ==="
crontab -l

echo "=== Service Status ==="
systemctl status crond | grep -E "Active|Loaded"

echo "✓ Cronie installed and configured on $server"
'
EOF

    if [ $? -eq 0 ]; then
        echo "✅ $server completed successfully"
    else
        echo "❌ Failed to configure $server"
    fi
done

echo ""
echo "========================================="
echo "✅ All servers configured!"
echo "========================================="
Enter fullscreen mode Exit fullscreen mode

Running the Script:

# Make script executable
chmod +x deploy_cron.sh

# Execute
./deploy_cron.sh
Enter fullscreen mode Exit fullscreen mode

Step 7: Verification Commands

Verify Cron Installation

# Check if cronie is installed
rpm -qa | grep cronie

# Output:
# cronie-1.5.7-16.el9.x86_64
# cronie-anacron-1.5.7-16.el9.x86_64
# crontabs-1.11-26.20190603git.el9.noarch
Enter fullscreen mode Exit fullscreen mode

Verify Crond Service

# Check service status
systemctl status crond

# Check if service is active
systemctl is-active crond
# Output: active

# Check if service is enabled
systemctl is-enabled crond
# Output: enabled
Enter fullscreen mode Exit fullscreen mode

Verify Cron Job

# View root's crontab
crontab -l

# Output:
# */5 * * * * echo hello > /tmp/cron_text

# Check for duplicate entries
crontab -l | sort | uniq -d

# Count cron jobs
crontab -l | wc -l
Enter fullscreen mode Exit fullscreen mode

Verify Execution

# Wait a few minutes, then check if file exists
ls -la /tmp/cron_text

# View file content
cat /tmp/cron_text
# Output: hello

# Check cron logs
tail -f /var/log/cron
Enter fullscreen mode Exit fullscreen mode

Remote Verification (All Servers)

# Check cron job on all servers
for server in stapp01 stapp02 stapp03; do
    echo "=== $server ==="
    ssh $server "crontab -l 2>/dev/null" | grep "*/5"
done
Enter fullscreen mode Exit fullscreen mode

Troubleshooting Common Issues

Issue 1: "crontab: command not found"

Solution:

yum install -y crontabs
Enter fullscreen mode Exit fullscreen mode

Issue 2: "Failed to start crond.service"

Solution:

# Check logs
journalctl -u crond -n 50

# Reload systemd
systemctl daemon-reload

# Try starting again
systemctl restart crond
Enter fullscreen mode Exit fullscreen mode

Issue 3: Cron job not executing

Solution:

# Check if crond is running
systemctl status crond

# Check cron logs
tail -f /var/log/cron

# Verify command works manually
echo hello > /tmp/cron_text

# Check SELinux (if enabled)
getenforce
# If enforcing, check SELinux context
ls -Z /tmp/cron_text
Enter fullscreen mode Exit fullscreen mode

Issue 4: Duplicate cron jobs

Solution:

# View all cron jobs
crontab -l

# Remove duplicates
crontab -l | sort -u | crontab -

# Or clear and recreate
crontab -r
(crontab -l 2>/dev/null; echo "*/5 * * * * echo hello > /tmp/cron_text") | crontab -
Enter fullscreen mode Exit fullscreen mode

Issue 5: "Permission denied" when editing crontab

Solution:

# Use sudo
sudo crontab -e

# Or become root
sudo su -
crontab -e
Enter fullscreen mode Exit fullscreen mode

Security Considerations

  1. Limit cron access using /etc/cron.allow and /etc/cron.deny
  2. Use absolute paths for all commands and scripts
  3. Set appropriate permissions on cron scripts (700 or 500)
  4. Log all cron actions and monitor logs regularly
  5. Use non-interactive shells for cron jobs
  6. Avoid passwords in scripts - use SSH keys or credential management tools

Example: Restrict Cron Access

# Allow only specific users
echo "root" > /etc/cron.allow
echo "tony" >> /etc/cron.allow

# Block specific users
echo "kodekloud_cap" > /etc/cron.deny
Enter fullscreen mode Exit fullscreen mode

Best Practices for Cron Jobs

1. Use Full Paths

# Bad (may fail due to PATH issues)
*/5 * * * * echo hello > /tmp/cron_text

# Good (uses absolute paths)
*/5 * * * * /usr/bin/echo hello > /tmp/cron_text
Enter fullscreen mode Exit fullscreen mode

2. Add Job Descriptions

# Add comments in crontab
# This cron job runs every 5 minutes
*/5 * * * * /usr/bin/echo hello > /tmp/cron_text
Enter fullscreen mode Exit fullscreen mode

3. Redirect Output

# Redirect stdout and stderr
*/5 * * * * /usr/bin/echo hello > /tmp/cron_text 2>&1

# Log to a file
*/5 * * * * /usr/bin/echo hello >> /var/log/hello.log 2>&1
Enter fullscreen mode Exit fullscreen mode

4. Use Scripts for Complex Tasks

# Cron job calling a script
*/5 * * * * /usr/local/bin/hello_script.sh
Enter fullscreen mode Exit fullscreen mode

5. Verify Before Deploying

# Test command manually
/usr/bin/echo hello > /tmp/cron_text

# Check exit code
echo $?
# Should be 0
Enter fullscreen mode Exit fullscreen mode

Complete Deployment Example

Here's an all-in-one example for deploying cron jobs:

#!/bin/bash

# Deployment script for cron jobs

# Configuration
SERVERS=("stapp01:tony:Ir0nM@n" "stapp02:steve:Am3ric@" "stapp03:banner:BigGr33n")
CRON_CMD="/usr/bin/echo hello > /tmp/cron_text"
CRON_SCHEDULE="*/5 * * * *"
CRON_JOB="$CRON_SCHEDULE $CRON_CMD"

echo "Starting cron deployment..."

for server_info in "${SERVERS[@]}"; do
    IFS=':' read -r server user pass <<< "$server_info"
    echo "Processing $server..."

    ssh "$user@$server" << EOF
echo '$pass' | sudo -S bash -c '
# Install cronie
yum install -y cronie

# Start and enable service
systemctl start crond
systemctl enable crond

# Add cron job
(crontab -l 2>/dev/null; echo "$CRON_JOB") | crontab -

# Verify
echo "Cron job added: \$(crontab -l | grep \"$CRON_SCHEDULE\")"
'
EOF

    echo "✓ $server completed"
    echo ""
done

echo "✅ All servers configured successfully!"
Enter fullscreen mode Exit fullscreen mode

Summary

In this guide, we covered:

Task Command/Step Status
Install cronie yum install -y cronie
Start crond service systemctl start crond
Enable crond on boot systemctl enable crond
Add cron job `(crontab -l; echo "*/5 ...") \ crontab -`
Verify installation crontab -l; systemctl status crond
Deploy across servers SSH + Heredoc script

Conclusion

Configuring cron jobs across multiple servers is a fundamental system administration task. By using the methods outlined in this guide, you can efficiently deploy and manage cron jobs on multiple servers in your infrastructure.

Top comments (0)