Bash Eval versus Arrays
Eval runs a string as code, while an array holds strings as data. A value that looks like a command stays plain text inside an array.
Eval runs the hidden command in the data
The value holds a second command after a semicolon. Eval runs both parts, so the injected line appears as its own line.
name="guest; echo injected line"
eval "echo hello $name"The same text stays harmless in an array
The array holds the whole value as one element. Echo prints the semicolon as text, and no second command runs.
parts=("hello" "guest; echo injected line")
echo "${parts[@]}"An array keeps a spaced filename whole
The filename holds a space, but the array passes it as one argument. Cat reads the one file instead of two broken names.
printf "note text\n" > "my notes.txt"
args=("cat" "my notes.txt")
"${args[@]}"Example
printf "first note\n" > "my notes.txt"
printf "second note\n" > "other.txt"
files=("my notes.txt" "other.txt")
cmd=(cat "${files[@]}")
"${cmd[@]}"Key points
- eval: a builtin that runs its argument as a Bash command.
- Injection: extra commands hidden inside data that eval then runs.
- Word splitting: the way an unquoted string breaks at spaces before a command runs.
- Array element: one value held exactly as written, spaces included.
- "${args[@]}": the expansion that passes each array element as one separate argument.
- Rule: build commands with arrays, and treat eval as a warning example only.
In this example, two files are created, one with a space in its name. The files array holds both names exactly as written. The cmd array builds a cat command from them, and running it prints both files in full.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
Why is eval dangerous for a value that came from outside the script?