- #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
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 $:
- In Lua code (
llex.c:667):$NAME→TK_ENVVARtoken → compiled togetenv("NAME")call - 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.