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.
1.4 KiB
1.4 KiB
06 — Implement piping between commands
Status: done
Syntax
Pipes are written inside backtick strings using |:
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 asparse_argv(). -
exec_pipeline()— executes a multi-stage pipeline:parse_argv()each stage- Creates N-1 inter-stage pipes + stdout/stderr capture pipes for the last stage
- Forks N children with appropriate stdin/stdout wiring
- Captures output from the last stage only
- 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 || cmd2or leading/trailing|) are errors
Tests
See testes/lush/piping.lua.