Environment variables stripped from command arguments before shell execution
Summary
Environment variables (e.g. $HA_TOKEN) are stripped from command arguments during preprocessing, but remain available in the environment. This causes commands like curl -H "Authorization: Bearer $TOKEN" to fail silently with an empty token value.
Environment
- Shell:
/opt/homebrew/bin/zshwith zprezto - Platform: macOS (darwin 24.0)
- curl: 8.7.1
- Token source:
$HA_TOKENset in~/.secrets, sourced by~/.zshrc - Execution: Commands run via
eval(visible inset -xtraces as+(eval):1>)
Reproduction
# This fails - token is stripped before eval
curl -s -H "Authorization: Bearer $HA_TOKEN" https://example.com/api
# Debug trace shows empty token:
set -x; curl -s -H "Authorization: Bearer $HA_TOKEN" https://example.com/api
# +(eval):1> curl -s -H 'Authorization: Bearer ' https://example.com/api
# But the variable exists and is exported:
printenv | grep HA_TOKEN # ✓ shows the token
export | grep HA_TOKEN # ✓ shows the token
echo $HA_TOKEN # ✓ works (shell builtin)
# External programs CAN access it via environment:
python3 -c "import os; print(os.environ['HA_TOKEN'])" # ✓ works
node -e "console.log(process.env.HA_TOKEN)" # ✓ works
sh -c 'echo $HA_TOKEN' # ✓ works (single quotes defer expansion)
Expected Behavior
Variable should expand normally in command arguments, consistent with shell builtins like echo.
Actual Behavior
Variable is stripped from arguments to external commands (curl, printf, etc.) but remains in the environment. The stripping happens before eval, as evidenced by the debug traces showing an empty value.
Workaround
Wrap commands in a subshell with single quotes so expansion happens in the subshell rather than during preprocessing:
sh -c 'curl -s -H "Authorization: Bearer $HA_TOKEN" https://example.com/api'
Scope
Affected:
- Any
$VARreference in arguments passed to external commands
Not affected:
- Shell builtins (
echo,export) - Variables inside single-quoted strings passed to subshells
- Direct environment access from within programs (
os.environ,process.env)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗