# procman
[](https://crates.io/crates/procman)
A foreman-like process supervisor written in Rust. Reads a `Procfile`, spawns all listed commands, multiplexes their output with name prefixes, and tears everything down cleanly when any child exits or a signal arrives.
## Usage
```
cargo install --path .
procman [OPTIONS] [PROCFILE]
```
Defaults to `Procfile` in the current directory if no path is given.
### Server mode
Run procman with a named FIFO to accept new process commands at runtime:
```
procman --server /tmp/procman.fifo
```
### Client mode
Send a command to a running procman server:
```
procman --client /tmp/procman.fifo "redis-server --port 6380"
```
The server parses the command line using the same rules as Procfile entries (including environment variable substitution) and spawns it into the existing process group.
An advisory `flock` on the Procfile prevents multiple instances from managing the same file simultaneously.
## Procfile Format
```
# Global environment variables (before any command lines)
DATABASE_URL=postgres://localhost/myapp
PORT=3000
# Commands — one per line
web serve --port $PORT
worker process-jobs --db $DATABASE_URL
```
- Lines starting with `#` are comments.
- Trailing `\` joins continuation lines.
- `KEY=value` lines before the first command set global environment variables.
- Inline `KEY=value` tokens at the start of a command line set per-command env vars. Values may be quoted: `FOO="hello world" myprogram`.
- `$VAR` references are substituted from the merged environment (inherited + global + inline). Undefined variables are a hard error — nothing is spawned.
- Process names are derived from the program basename. Duplicates get `.1`, `.2` suffixes.
- **Note:** Unlike a POSIX shell, inline env vars are passed to the child process *and* substituted into the command line. `FOO="abc" echo $FOO` will print `abc`, whereas a shell would expand `$FOO` before the assignment takes effect and print an empty line.
## Behavior
- All children share a process group.
- stderr is merged into stdout per-process.
- Output is prefixed with the process name, right-aligned and padded.
- Per-process logs are written to `./logs/<name>.log`.
- On SIGINT or SIGTERM, all children receive SIGTERM. After a 2-second grace period, remaining processes are sent SIGKILL.
- procman exits with the first child's exit code.
## License
MIT