schedls
Inspect and manage the things Linux runs later.
schedls is a CLI tool for inspecting and managing cron jobs and
systemd timers through one transparent interface. It is a management and
inspection layer over the operating system's native schedulers — it is not a
daemon, not a queue, and not a replacement scheduler.
$ schedls
NAME SCHEDULE NEXT BACKEND SCOPE STATUS
backup daily at 02:00 tomorrow 02:00 systemd user waiting
cleanup 0 4 * * 0 Sun 04:00 cron user active
logrotate daily — systemd system waiting
If you uninstall schedls, everything it created keeps working: a timer is an
ordinary systemd unit, and a cron job is an ordinary crontab entry.
Install
From the package repository
Native .deb and .rpm packages are published in the shared
SysMD package repository.
Debian / Ubuntu
sudo mkdir -p /usr/share/keyrings
curl -fsSL https://repo.sysmd.uk/sysmd/sysmd.gpg | sudo gpg --dearmor -o /usr/share/keyrings/sysmd.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/sysmd.gpg] https://repo.sysmd.uk/sysmd/debian stable main" | sudo tee /etc/apt/sources.list.d/sysmd.list
sudo apt update
sudo apt install schedls
The signing key fingerprint is
0032C71FA6A11EF9567D4434C5C06BD4603C28B1.
Fedora / RHEL
sudo rpm --import https://repo.sysmd.uk/sysmd/sysmd.gpg
sudo tee /etc/yum.repos.d/sysmd.repo > /dev/null << 'EOF'
[sysmd]
name=SysMD Repository
baseurl=https://repo.sysmd.uk/sysmd/rpm/$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://repo.sysmd.uk/sysmd/sysmd.gpg
EOF
sudo dnf upgrade --refresh
sudo dnf install schedls
From PyPI
$ pipx install schedls
# or
$ pip install --user schedls
python -m schedls works too. Python 3.11+.
Bash completion
Enable opt-in completion for the current Bash session:
eval "$(register-python-argcomplete schedls)"
Add that line to your shell profile to enable it in future sessions.
Examples
Discover everything visible to you:
$ schedls
$ schedls --system
$ schedls --backend cron
Explore a native calendar expression without creating anything:
$ schedls calendar 'Mon..Fri 02:30'
$ schedls calendar --next 10 --utc daily
Create a user systemd timer:
$ schedls new backup --timer --daily 02:00 --persistent -- /usr/local/bin/backup /srv/data
Create a cron job:
$ schedls new cleanup --cron --cron-expr '0 4 * * 0' -- /usr/local/bin/cleanup
$ schedls new backup --cron --daily 02:00 --env TZ=UTC -- /usr/local/bin/backup
Cron --env values apply only to that managed job; they are scheduler
configuration rather than secret storage. Managed cron jobs can also be enabled
or disabled without deleting their saved schedule.
Create a system cron drop-in as root (runs as root unless --run-as is given):
$ sudo schedls new updates --cron --system --daily 03:00 -- /usr/local/bin/updates
Prefer to be guided? Add -i/--interactive to new or edit and any
omitted field is prompted for. Flags you do pass become pre-filled defaults:
$ schedls new backup -i
$ schedls edit backup -i
For new, the wizard asks for the scope (user or system) unless --user or
--system was given; a system cron job then asks which user it should run as
(default root). Interactive mode is line-based (no external editor or pager),
requires a terminal, and cannot be combined with --json. The collected values
are shown in the usual preview and still require confirmation before anything
is written.
Inspect, change, disable, remove:
$ schedls show backup
$ schedls edit backup --daily 03:00
$ schedls disable backup
$ schedls rm backup
$ schedls logs backup
Check what this host can do:
$ schedls doctor
Every mutating command supports --dry-run, and --yes for scripts. Machine
output is available with --json.
Design promises
schedls does not:
- run a background daemon;
- listen on a network port;
- make network requests;
- automatically invoke
sudo; - execute discovered scheduled commands;
- open an editor or pager while managing jobs;
- use a shell internally for helper commands;
- modify unmanaged schedules by default.
See SECURITY.md and docs/security-model.md.
Documentation
- docs/cli.md — every command, option and exit code
- docs/architecture.md
- docs/security-model.md
- docs/systemd.md
- docs/cron.md
Development
$ poetry install
$ poetry run pre-commit install # check hooks on every commit
$ poetry run pre-commit run --all-files
$ poetry run pytest
$ poetry run mypy
Formatting and linting use ruff; security
scanning uses Bandit; both run through
pre-commit alongside trailing-whitespace, end-of-file,
YAML and TOML checks. CI runs on pull requests, applying the same hooks and a
strict type check on Python 3.13, a pip-audit dependency audit, and the test
suite on Python 3.11 and 3.13. Dependency security updates are handled centrally
by Renovate. Build distributions locally with poetry build.
Support
If you find schedls useful, consider supporting its development:
