eval — Parse and execute a string as if it were a shell command across all 5 shells
Equivalents in every shell
eval "$cmd"Bash builtin. Joins its arguments with spaces, then parses and runs the result as a shell line. Variables, expansions, redirections — all expanded a second time.
eval $cmdFish builtin (deprecated in 3.0 but still functional). The modern fish recommendation is command substitution `($cmd)` or `string split` plus direct invocation.
Invoke-Expression $cmdAliased as `iex`. Parses and runs a string as PowerShell. Same security model as `eval` — never pass untrusted input.
call %cmd%`call` re-parses variable references but does NOT do a second pass on aliases, redirections, or special chars. There is no true `eval` in cmd — for full re-parsing, drop to PowerShell `iex` or write a helper `.bat`.
Worked examples
Evaluate `ssh-agent` startup output to set env vars
eval "$(ssh-agent -s)"eval "$(ssh-agent -s)"eval (ssh-agent -c | string collect)ssh-agent | Out-String | Invoke-ExpressionBuild and run a command from variables
cmd="ls -la /tmp"; eval "$cmd"$cmd = "Get-ChildItem -Force /tmp"; Invoke-Expression $cmdLoad shell config printed by a tool (rbenv, direnv, mise)
eval "$(rbenv init -)"eval "$(rbenv init - zsh)"rbenv init - fish | sourcerbenv init - powershell | Out-String | Invoke-ExpressionGotchas
- `eval` with any user-controlled input is a command-injection vulnerability — `eval $name` where `$name` contains `; rm -rf ~` runs the destructive command. Always quote (`eval "$cmd"`) AND audit the source of the string.
- Double expansion means quotes and backslashes need to be escaped *twice*. `eval echo \\"hi\\"` yields `hi`. This is famously hard to get right; prefer array-based command construction (`cmd=(ls -la /tmp); "${cmd[@]}"`) where possible.
- Fish deprecates `eval` and recommends string-builtins. Modern fish patterns like `rbenv init - fish | source` avoid `eval` entirely by piping the script body into `source`.
- PowerShell `Invoke-Expression` is the official equivalent and carries an explicit security warning in `Get-Help iex` — the language even has an analyzer rule (`PSAvoidUsingInvokeExpression`) that flags its use.
- `call %cmd%` in cmd does NOT behave like `eval` — it expands `%var%` once but treats the result as a single command, not a script line. Pipes, redirections, and `&&` inside `%cmd%` are passed literally and almost never work.
WSL & PowerShell Core notes
Common tasks using eval
- Check if a script is sourced or executed
Detect at runtime whether the current script was sourced into the parent shell (`. script` / `source script`) or executed in a subshell (`bash script`) — so the same file can be used both as a library and as a CLI.
- Escape a string for safe shell use
Quote / escape a string so it survives word-splitting, glob expansion, and interpretation as multiple arguments — the fix for "spaces in filename break my script" and shell-injection bugs.