Files
lush/issues/06-piping.md
Cormac Shannon d0181e685d Implement piping between commands in backtick syntax (issue #06)
Add split_pipeline() to split command strings on unquoted | and
exec_pipeline() to fork N children connected by inter-stage pipes.
Only the last stage's stdout/stderr are captured; middle stages'
stderr is inherited. Exit code comes from the last stage.
2026-03-01 22:17:30 +00:00

41 lines
1.4 KiB
Markdown

# 06 — Implement piping between commands
**Status:** done
## Syntax
Pipes are written inside backtick strings using `|`:
```lua
local r = `ls -l | grep ".lua" | wc -l`
```
The `|` operator between backtick expressions remains Lua's bitwise OR — pipes only work *within* a single backtick command string.
## Implementation
Implemented in `lcmd.c` with two new functions:
- **`split_pipeline()`** — scans the command string for `|` outside single/double quotes, splits into an array of stage strings (up to 64 stages). Reuses the same quote-tracking logic as `parse_argv()`.
- **`exec_pipeline()`** — executes a multi-stage pipeline:
1. `parse_argv()` each stage
2. Creates N-1 inter-stage pipes + stdout/stderr capture pipes for the last stage
3. Forks N children with appropriate stdin/stdout wiring
4. Captures output from the last stage only
5. Returns `{code=last_exit_code, stdout=captured, stderr=captured}`
`luaB_command()` calls `split_pipeline()` first. Single-stage commands (no `|`) fall through to the original single-command codepath unchanged.
## Behaviour
- Exit code is from the **last** pipeline stage (like bash)
- Only the last stage's stdout/stderr are captured in the result table
- Middle stages' stderr is inherited (goes to terminal)
- Quoted `|` characters (single or double quotes) are not pipe separators
- Empty pipeline stages (e.g. `cmd1 || cmd2` or leading/trailing `|`) are errors
## Tests
See `testes/lush/piping.lua`.