bgrun is a small background command manager for local machines and small servers.
It runs any command in the background, keeps a state file, writes logs, and lets you
list, inspect, stop, restart, remove, and prune tasks.
It is intentionally narrower than systemd, Supervisor, PM2, Docker Compose, or a
job queue. It does not do boot-time startup, crash auto-restart, dependency graphs,
resource isolation, clustering, remote control, or a Web UI.
Build locally:
go build -o bgrun .Put the resulting bgrun binary somewhere on your PATH.
The release form is intended to be a single binary per OS/architecture. After publishing GitHub Release assets, installation can be:
curl -fsSL https://raw.githubusercontent.com/randolph555/bgrun/main/install.sh | BGRUN_REPO=randolph555/bgrun shbgrun start python3 app.py
bgrun start api -- python app.py
bgrun start web --cwd ./site -- npm run dev
bgrun start api --log-dir ./logs -- python app.py
bgrun list
bgrun status api
bgrun top
bgrun top 'java*'
bgrun logs api
bgrun logs -f api
bgrun stop api
bgrun stop 'java*'
bgrun stop-all
bgrun restart api
bgrun rm api
bgrun rm-all
bgrun prunelist and status include a current snapshot of CPU, memory, ports, and uptime.
top refreshes the same view continuously.
stop, rm, and top accept a shell-style glob (for example 'java*' or
'web-?') matched against task names. Quote the pattern so your shell does not
expand it first. Because rm accepts a glob, a pattern like '*' removes every
matching task at once; running tasks are still protected unless you pass
--force.
bgrun start py-api -- python3 app.py
bgrun start python3 app.py
bgrun start node-web -- npm run dev
bgrun start java-api -- java -jar app.jar
bgrun start go-api -- ./server
bgrun start rust-worker -- cargo run --release
bgrun start conda-api -- conda run -n myenv python app.py
bgrun start shell-job -- ./run.shUninstall the binary installed by install.sh:
curl -fsSL https://raw.githubusercontent.com/randolph555/bgrun/main/install.sh | BGRUN_REPO=randolph555/bgrun sh -s -- uninstallRemove state and logs too:
curl -fsSL https://raw.githubusercontent.com/randolph555/bgrun/main/install.sh | BGRUN_REPO=randolph555/bgrun BGRUN_REMOVE_STATE=1 sh -s -- uninstallUse -- between the task name and the command so bgrun flags never collide
with the command's own flags:
bgrun start worker -- ./worker --port 9000 --debug--cwd DIR run the command from DIR
--env KEY=VALUE add or override an environment variable, repeatable
--log FILE choose a log file
--log-dir DIR choose a log directory; file name stays <name>.log
--truncate truncate the log before starting
--replace stop and replace an existing running task with the same nameBy default, state lives in:
~/.local/state/bgrun
Task logs live in the command working directory:
./.bgrun/<name>.log
Use --cwd DIR to choose the working directory, --log FILE to choose a
specific log file, or --log-dir DIR to keep the automatic <name>.log file
name but write it somewhere else.
Set BGRUN_HOME to override the state directory:
BGRUN_HOME=/tmp/bgrun-test bgrun start demo -- sleep 100bgrun manages local process lifecycle only:
startcreates a separate process group sostopcan terminate the command and its children together.stopsendsSIGTERM, waits for a timeout, then sendsSIGKILL.restartreuses the original command, working directory, environment overrides, and log file.listandstatuscheck whether the stored process is still alive.- PID reuse is guarded by a process fingerprint. Linux uses
/proc; macOS usespsoutput. - State writes are protected by a lock file and an atomic rename.
Unsupported by design:
- Windows support
- boot-time service installation
- crash auto-restart / keepalive supervision
- dependency ordering
- resource limits / containers
- multi-host orchestration
Those features belong in tools like systemd, Supervisor, PM2, Docker, or a real
job queue.
The repository includes runnable smoke tests for shell, Python, Java, Go, Rust,
and JavaScript. The demo programs are minimal local web services so status,
list, and top can show listening ports and resource usage:
scripts/test-languages.shThe script builds or runs each language sample through bgrun, verifies logs,
tests restart, stops the process group, and prunes exited tasks. If a language
runtime is missing or broken locally, that case is reported as skipped. For Node,
the script first tries node from PATH, then tries ~/.nvm/nvm.sh.
