Files
lush/issues/25-envvar-expansion-in-commands.md
Cormac Shannon 42baabde34 Implement $VAR expansion in commands (issue #25)
Extend read_command_body() to detect $NAME and trigger interpolation
using the same fragment-split mechanism as ${expr}. The lexer collects
the identifier into cmd_envvar; the parser's unified parseinterp()
branches on it to emit tostring(getenv(NAME)).
2026-03-18 08:35:46 +00:00

52 lines
1.6 KiB
Markdown

# 25 — Environment variable expansion in commands
**Status:** done
## Problem
`$VAR` syntax works in Lua expressions but not inside commands:
```lua
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:
```lua
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`): `$NAME``TK_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:
```lua
!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:
```lua
!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.