Skip to main content

Command Palette

Search for a command to run...

Make Linux React Instantly When a File Appears

🚀 No Cron Needed

Published
6 min read
P

As a associate system administrator I worked on Redhat Linux servers, including user management, permissions, services, and performance monitoring Automated routine administrative tasks using Bash scripting and cron jobs, reducing manual effort by ~30% I am aws certified sysops administrator and Google Certified Cloud Engineer. Determined to transition my career into cloud architect /Cloud Support role

Most automation in Linux relies on cron.

And cron has one big flaw: it waits.

If your job runs every minute, a user might wait 59 seconds before anything happens. That’s not instant. That’s polling.

Today we’re going deeper.

We’re building an event-driven system using systemd.path so Linux reacts immediately when a file appears in a directory.

No cron.
No loops.
Kernel-level file watching.


🧠 The Scenario — The “Hot Folder”

You manage a shared directory:

/srv/uploads

Users from:

  • Windows (Samba)

  • Linux (SCP/SFTP)

constantly drop raw image files into it.

Your architecture must:

  • ✅ React instantly when a file appears

  • ✅ Trigger /usr/local/bin/process_images.sh immediately

  • ❌ Not use cron

  • ✅ Use systemd.path (inotify-based kernel watcher)


🏗 Architecture Overview

We will create two linked systemd units:

  1. hotfolder.service → The worker (runs the script)

  2. hotfolder.path → The watcher (detects file changes)


Step 1 — The Worker (Service Unit)

Create:

/etc/systemd/system/hotfolder.service
[Unit]
Description=Process images dropped into /srv/uploads
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/process_images.sh
WorkingDirectory=/srv/uploads

User=root
Group=root

Nice=5
IOSchedulingClass=best-effort
IOSchedulingPriority=6
UMask=0022

🔍 Why Type=oneshot?

Because this is not a daemon.
It runs once and exits after processing files.

🤔 Why No [Install] Section?

We do not enable the service directly.

The path unit triggers it automatically.

That’s why the service does not need:

[Install]
WantedBy=...

Step 2 — The Watcher (Path Unit)

Create:

/etc/systemd/system/hotfolder.path
[Unit]
Description=Watch /srv/uploads and trigger image processing

[Path]
PathChanged=/srv/uploads

[Install]
WantedBy=multi-user.target

🔥 PathChanged= or PathModified= ?

Use:

PathChanged=

Why?

  • It triggers when directory contents change

  • Detects new files created or renamed into place

  • Perfect for “a file appeared” scenarios

PathModified= is more about metadata or attribute changes.

For hot folders → PathChanged is ideal.


🧩 How Does the Path Unit Know Which Service to Run?

Simple rule:

If the file is named:

hotfolder.path

Systemd automatically looks for:

hotfolder.service

They are linked by name.

(You can override this with Unit= inside [Path], but default naming is clean and recommended.)


Step 3 — Activate the Monitoring

Reload systemd:

systemctl daemon-reload

Enable and start the watcher:

systemctl enable --now hotfolder.path

⚠️ Important:
You enable the path unit, not the service.


🔎 Verification

Check watcher status:

systemctl status hotfolder.path

Check if service ran:

systemctl status hotfolder.service

Live logs:

journalctl -u hotfolder.service -f

Now drop a file into:

/srv/uploads

And watch it trigger instantly.

No waiting.
No cron delay.
Pure event-driven Linux.


🏁 Final Thoughts

This pattern is extremely powerful.

You can use systemd.path for:

  • Auto-processing uploads

  • Triggering security scans

  • Running ETL jobs

  • Log pipeline ingestion

  • Automated backups

Instead of polling, you let the kernel notify systemd via inotify.

That’s clean architecture.
That’s efficient.
That’s production-grade Linux.


Event-Driven Linux Automation with systemd.path + systemd.timer (Production-Ready)

In the previous version, we built a hot folder using systemd.path to instantly react when a file appears.

Now we’re going to:

  • Combine systemd.path + systemd.timer

  • Harden the service (zero-trust style)

  • Run it as a restricted service account

  • Make it production safe

This is how you design Linux automation like an architect — not like a cron hobbyist.


🧠 The Scenario (Revisited)

Directory: /srv/uploads

Requirements:

  • Instant reaction when a file appears

  • Periodic safety sweep in case something was missed

  • Strong service hardening

  • Run with least privilege


🏗 Final Architecture

We will create:

  1. hotfolder.service → Worker

  2. hotfolder.path → Real-time watcher

  3. hotfolder.timer → Periodic fallback trigger

  4. Dedicated system user → imgprocessor

Why both path + timer?

Because event systems can fail if:

  • inotify limits are exceeded

  • files are moved in unusual ways

  • system restarts mid-upload

The timer acts as a safety net.


Step 1 — Create Restricted Service Account

Never run automation as root unless required.

Create a system account:

useradd --system --no-create-home --shell /sbin/nologin imgprocessor

Set permissions:

chown -R imgprocessor:imgprocessor /srv/uploads
chmod 750 /srv/uploads

Now only that service account can process uploads.


Step 2 — Hardened Worker Service

Navigate to path: /etc/systemd/system/hotfolder.service

[Unit]
Description=Secure Image Processing Service
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/process_images.sh
WorkingDirectory=/srv/uploads

User=imgprocessor
Group=imgprocessor

# 🔐 Security Hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/srv/uploads
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictRealtime=true
LockPersonality=true
MemoryDenyWriteExecute=true

UMask=0027

🔒 What These Security Options Do

  • NoNewPrivileges=true → Prevents privilege escalation

  • PrivateTmp=true → Isolates /tmp

  • ProtectSystem=strict → Makes system directories read-only

  • ProtectHome=true → Blocks access to user home dirs

  • ReadWritePaths= → Only this directory is writable

  • MemoryDenyWriteExecute=true → Mitigates memory exploits

  • LockPersonality=true → Prevents syscall personality changes

This turns your service into a sandbox.

This is enterprise-level hardening.


Step 3 — Real-Time Watcher (Path Unit)

edit path: /etc/systemd/system/hotfolder.path

[Unit]
Description=Watch /srv/uploads for changes

[Path]
PathChanged=/srv/uploads

[Install]
WantedBy=multi-user.target

This triggers hotfolder.service instantly.


Step 4 — Add a Safety Timer

Even the best event systems need backup.

Create:

/etc/systemd/system/hotfolder.timer

[Unit]
Description=Periodic Image Processing Fallback

[Timer]
OnBootSec=2min
OnUnitActiveSec=5min
Unit=hotfolder.service

[Install]
WantedBy=timers.target

🕒 What This Does

  • Runs 2 minutes after boot

  • Re-runs every 5 minutes after last execution

  • Directly triggers the same service

Now you have:

⚡ Instant event processing
🛟 Periodic verification sweep

This is resilient automation.


Step 5 — Activate Everything

systemctl daemon-reload
systemctl enable --now hotfolder.path
systemctl enable --now hotfolder.timer

Check status:

systemctl list-timers
systemctl status hotfolder.path

🏁 Final Architecture Flow

  1. User drops file

  2. systemd.path detects change via inotify

  3. hotfolder.service runs instantly

  4. Every 5 minutes, systemd.timer ensures nothing was missed

  5. Service runs in a hardened sandbox

  6. No root. No cron. No polling.


💡 Why This Design Is Superior to Cron

Cronsystemd.path + timer
PollingEvent-driven
DelayedInstant
Often runs as rootLeast privilege
No sandboxingStrong isolation
No fallback logicBuilt-in resilience

🧨 Production Considerations

  • Increase inotify limit:

      systemctl fs.inotify.max_user_watches=524288
    
  • Log to journald with structured output

  • Add rate limiting if upload bursts are heavy

  • Move processed files to /srv/processed


🚀 Final Thoughts

This design transforms Linux into an event-driven automation engine.

You combined:

  • systemd.path → real-time kernel-level detection

  • systemd.timer → reliability layer

  • Hardened service sandbox

  • Least privilege execution

That’s not just automation. This is production architecture.

This design transforms Linux into an event-driven automation engine.