pend β do now, wait later π
pend
is a tiny cross-platform job runner that lets you fire-and-forget
processes now and deal with their output later β all while keeping logs
tidy, exit statuses intact, and your shell scripts blissfully simple.
# Run two jobs in parallel β¦
pend do backend ./scripts/build_backend.sh
pend do frontend ./scripts/build_frontend.sh
# β¦ wait for them whenever you want (combined coloured output!)
pend wait backend frontend
# Clean up once you are done
pend clean --all
Why wrestle with &
, wait
, and brittle tee
pipelines when one binary
does all the heavy lifting for you?
π¦ Installation
# or grab a pre-built release asset from GitHub
The crate is 100 % Rust, no native libraries, so a static binary drops out on all tier-1 platforms (Windows / macOS / Linux β x86-64 & aarch64).
π§ Mental model
Command | What it does |
---|---|
pend do <job> <cmd β¦> |
Launches <cmd> detached in the background. Captures its stdout, stderr, exit code, metadata, and a combined .log stream. Optional flags --timeout <secs> and --retries <n> kill or re-run the command automatically. |
pend wait <job β¦> |
Blocks until the supplied job(s) finish. Streams their output in the original order and exits with the very same code the first failing job produced. |
pend clean [--all | <job β¦>] |
Deletes artifacts to free disk space. Skips jobs that are still running. |
pend tui |
Opens a super-lightweight TUI that auto-refreshes and shows a live list of all jobs (press q to quit). |
Thatβs the entire user-facing surface β four deliberately boring verbs.
β¨ What you get β out of the box
β’ Structured artifacts β every job yields predictable files: .out
, .err
, .log
, .exit
, .json
, .signal
(Unix) β all plain text or JSON.
β’ Crash-safe exit codes β the .exit
marker is written before log pipes are closed so pend wait
never hangs on a half-dead worker.
β’ Coloured multi-job output β pend wait a b c
interleaves logs with deterministic colours and clear β / β status lines.
β’ Size-bounded log rotation β --max-log-size 10M
keeps CI artifacts small yet complete.
β’ Wall-clock timeout β pend do <job> --timeout 30 <cmd β¦>
terminates runaway processes after 30 s and marks the job as failed.
β’ Automatic retries β --retries 3
re-runs flaky commands up to three times until one attempt succeeds.
β’ Strong validation & security β path traversal is impossible, job names are capped at 100 characters, and an advisory .lock
prevents concurrent duplicates.
β’ Platform quirks handled β symlink tmpdirs on macOS, MAX_PATH
on Windows, signals on Unix β tested on all three major OSes in CI.
β’ Single static binary β integrates into any Bash / PowerShell / CMD script without pulling in a runtime.
π Artifact layout
Jobs live in a single directory (defaults to $TMPDIR/pend
, override via
--dir
or PEND_DIR
). Files follow <job>.<ext>
:
File | Purpose |
---|---|
foo.out / foo.err |
Raw stdout / stderr as produced. |
foo.log (+ .log.1 β¦) |
Chronological merged log (rotated). |
foo.exit |
Numeric exit code written first. |
foo.json |
Pretty-printed metadata (command, PID, UTC timestamps). |
foo.signal (Unix) |
Raw signal number, if any. |
foo.lock |
Advisory lock file; safe to delete when the job is not running. |
Everything is human-readable β cat
, jq
, or even Notepad work fine.
π Example: parallel build & package
# Kick off long-running tasks
# Meanwhile run unit tests β¦
# Stream & fail fast once the first build fails
# Ensure the linter finishes within 60 seconds and automatically retries once
# if it flaps due to I/O hiccups.
# Package artifacts only if both succeeded
# Upload artifacts, then clean workspace
π Under the hood
- Worker process β spawns child cmd, merges pipes via channel fan-in, writes JSON, exits.
- File watcher β
pend wait
uses the cross-platformnotify
crate for instant.exit
detection; falls back to exponential back-off polling if necessary. - No async runtime β plain threads & channels keep the binary small (< 1 MiB on Linux/musl).
π Prior art
GNU parallel
, xargs -P
, make -j
, ninja
, taskwarrior
, just
, cargo-make
β¦ all wonderful β yet none hit the sweet spot of ad-hoc, nameable, parallel shell jobs with deterministic logs.
pend does.
Made with β€οΈ & Rust β so you can do now, wait later.