cmd_lib
Rust macros for writing shell-script-like tasks without spawning a shell
Repository Health
Technical Analysis
cmd_lib provides run_cmd! and run_fun! macros that let Rust programs run external commands with shell-like piping and redirection syntax, but with compile-time parsing and no shell process ever spawned. It targets the common case of porting ad-hoc shell scripts into maintainable Rust code without losing the ergonomic cmd | cmd2 > file syntax developers already know.
Because command parsing happens at compile time via procedural macros, most command-composition errors surface as compiler errors rather than runtime failures, and parameter substitution is done safely by construction, avoiding the command-injection pitfalls of naive shell string interpolation. The library also ships builtin commands (cd, echo, logging levels), thread-local globals, and lower-level spawn!/spawn_with_output! macros for background process control.
What You Get
run_cmd!andrun_fun!macros for executing commands and capturing their output as Result-wrapped values- Native pipe (
|) and redirection syntax resolved entirely at compile time, no shell subprocess involved - Safe, injection-resistant variable interpolation (
$var,${var},$[vec]) into command arguments - Builtin commands (
cd,echo,ignore,error/warn/info/debug/trace) plus integration with thelogcrate - Lower-level
spawn!/spawn_with_output!macros and thread-local global macros (tls_init!/tls_get!/tls_set!) for background process and state management
Common Use Cases
- Rewriting a fragile bash/shell deployment or CI script as a typed, compiled Rust binary
- Composing external command pipelines (grep/awk/sort-style chains) inside a Rust CLI tool
- Running system commands with dynamic, user-influenced arguments while avoiding shell injection
- Building small ops/automation tools that need process spawning, logging, and directory-scoped
cdsemantics
Under The Hood
Architecture: The crate splits into a macros workspace member (the cmd_lib_macros proc-macro crate performing compile-time lexical/syntactic parsing of the DSL) and the runtime crate itself, whose src/process.rs (843 lines) implements process spawning, piping, and I/O plumbing, src/builtins.rs implements the built-in commands (cd, echo, logging), src/io.rs handles redirection, and src/thread_local.rs implements the tls_*! macros. src/lib.rs is primarily macro-facing documentation and re-exports, keeping the public surface small relative to the implementation.
Tech Stack: Rust 2024 edition, MSRV 1.88, depending on os_pipe for cross-platform pipe creation, faccess for permission checks, log/env_logger for its logging integration, and optional tracing/build-print features for alternative logging backends. Dev-dependencies (rayon, clap, tracing-subscriber) support its examples and test suite rather than the library itself.
Code Quality: tests/test_macros.rs (380 lines) exercises the macro-generated code across piping, redirection, builtins, and error paths, and the crate favors returning Result types (CmdResult, FunResult) over panics for command failures, which is consistent with the library’s stated goal of surfacing errors explicitly rather than silently. Dual MIT/Apache-2.0 licensing and a rustfmt.toml indicate standard Rust ecosystem conventions are followed.
API Design: The macro-based DSL is the library’s central design bet — run_cmd!(du -ah $dir | sort -hr | head -n 10) reads almost identically to the equivalent bash, which minimizes the porting cost from shell scripts while gaining Rust’s type system and compile-time checks. This trades some discoverability (IDE tooling sees macro invocations, not plain function calls) for very low boilerplate at the call site, which the maintainer explicitly frames as the core value proposition over hand-rolling std::process::Command.
Used by 2 apps in this directory
AppFlowy
Productivity · Project Management · Collaboration
The open-source AI workspace that puts your data, your rules — with local LLMs, CRDT collaboration, and full self-hosting built in.
ParadeDB
Search · Databases · Analytics
Born out of Y Combinator's S2023 batch, ParadeDB is a Postgres extension that delivers Elasticsearch-quality BM25 search and real-time analytics without a separate search cluster to manage.