Files
lush/issues/25-envvar-expansion-in-commands.md
Cormac Shannon 08df164692 Add issues #25, #26, #27; update #7 and #22 statuses
- #25: $VAR expansion in commands
- #26: Shell abbreviations and user-extensible builtins
- #27: $(cmd) subcommand syntax
- #22: Updated with implementation details (in progress)
- #7: Standardize status label
2026-03-15 19:33:19 +00:00

1.6 KiB

25 — Environment variable expansion in commands

Status: open

Problem

$VAR syntax works in Lua expressions but not inside commands:

print($PATH)        -- works: $PATH is lexed as TK_ENVVAR, expanded via getenv()
!echo $PATH         -- broken: $PATH is kept as literal text, passed unexpanded

The same applies to backtick commands:

local r = `echo $HOME`   -- $HOME is literal, not expanded

Why it happens

The lexer has two separate paths for $:

  1. In Lua code (llex.c:667): $NAMETK_ENVVAR token → compiled to getenv("NAME") call
  2. In command mode (llex.c:518): $ without { is saved as a literal character in the command string buffer

Only ${expr} interpolation works in commands — it enters a Lua expression context and returns the result inline. Bare $NAME is passed through verbatim.

Since commands are executed via fork/exec (not through /bin/sh), there is no shell to expand $PATH at runtime either.

Expected behavior

$VAR should expand in commands the same way it does in Lua expressions:

!echo $HOME          -- should print /Users/nik
!echo $PATH          -- should print the PATH value
local r = `echo $HOME`  -- r.stdout should contain /Users/nik

Workaround

Use ${expr} interpolation:

!echo ${$HOME}

Possible fix

In read_command_body() (llex.c:518), when $ is followed by an identifier, emit the current command fragment and produce a TK_ENVVAR-equivalent expansion inline — similar to how ${expr} already splits the command string to insert interpolated values.