Filters
How to search
  • Plain words find names, texts and examples.
  • "two words" finds the exact phrase.
  • --name or -x finds an option.
  • #word looks only inside commands.
  • @grep finds lessons and labs that use grep.
  • Filters: cat:network · in:labs · in:notes · level:rhcsa · ch:8 · root:yes. Put ! before a word to leave it out. OR between words means one of them.
  • ↑ ↓ to move · Enter to open · Esc to close · / to search

Chapter 9Name in the course: Command-line tools and scheduling

Build command-line tools and schedule them

A good admin script feels like a real command: --help, options with defaults, clear errors, exit codes. argparse builds that in a few lines; a systemd timer runs it on a schedule.

  • 4 Lessons
  • 3 Commands

$ run as a normal user# run as root (or with sudo)

9.1

Parse arguments with argparse

Declare the options; argparse makes --help, checks types and shows errors.

diskcheck.py
#!/usr/bin/env python3
"""Check disk usage and exit with 0 (OK), 1 (WARNING) or 2 (CRITICAL)."""
import argparse
import shutil
import sys
 
 
def level_for(pct: float, warn: int, crit: int) -> int:
    return 2 if pct >= crit else 1 if pct >= warn else 0
 
 
def main() -> int:
    p = argparse.ArgumentParser(description=__doc__)
    p.add_argument("paths", nargs="*", default=["/"], help="mount points to check")
    p.add_argument("-w", "--warn", type=int, default=80, help="warning level in percent")
    p.add_argument("-c", "--crit", type=int, default=90, help="critical level in percent")
    p.add_argument("-q", "--quiet", action="store_true", help="print only problems")
    args = p.parse_args()
 
    worst = 0
    for path in args.paths:
        u = shutil.disk_usage(path)
        pct = u.used / u.total * 100
        level = level_for(pct, args.warn, args.crit)
        worst = max(worst, level)
        if level or not args.quiet:
            print(f"{['OK', 'WARNING', 'CRITICAL'][level]:8} {path} {pct:.0f}%")
    return worst
 
 
if __name__ == "__main__":
    sys.exit(main())
./diskcheck.py --help
./diskcheck.py / /var -w 70
echo $?

Commands in this lesson

9.2

Install the tool for everyone

Put it in /usr/local/bin without the .py, executable, owned by root.

install -m 755 diskcheck.py /usr/local/bin/diskcheck
diskcheck -q /

9.3

Schedule it with a systemd timer

A service runs the script; a timer starts the service (see Schedule system jobs).

/etc/systemd/system/diskcheck.service
[Unit]
Description=Disk usage check
 
[Service]
Type=oneshot
ExecStart=/usr/local/bin/diskcheck -q / /var /home
/etc/systemd/system/diskcheck.timer
[Unit]
Description=Disk check every 15 minutes
 
[Timer]
OnCalendar=*:0/15
Persistent=true
 
[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now diskcheck.timer
journalctl -u diskcheck.service -n 10

9.4

Test your code

Small functions + pytest = confidence when you change a script later.

test_diskcheck.py
from diskcheck import level_for
 
 
def test_levels():
    assert level_for(50, warn=80, crit=90) == 0
    assert level_for(85, warn=80, crit=90) == 1
    assert level_for(95, warn=80, crit=90) == 2
pip install pytest ruff
ruff check .
pytest -q

At work

Run ruff and pytest in CI on every push — see Build a CI pipeline.

All commands in this chapter