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

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 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.