Why should eval be avoided in Bash, and what should I use instead?

eval is a built-in Bash command that concatenates its arguments into a single string, joins them with spaces, then executes that string as a bash command. While powerful, eval poses serious security risks and should generally be avoided.

How eval Works

Let's see a basic example of eval in action ?

$ var="echo hello"
$ echo $var
$ eval $var

Running the above code gives us the following result ?

echo hello
hello

When eval is applied, the variable expands and gets executed as a command, no longer behaving as just a string.

Security Problems with eval

The main issue with eval is command injection. Malicious users can inject arbitrary commands into variables or function parameters, potentially executing dangerous operations with the script owner's privileges.

Vulnerable Script Example

Consider this function that uses eval ?

print_array() {
    in_array=$1
    eval echo ""The first value in the array is \${$in_array[0]}""
}

fruits=(apple orange grapes berry)
print_array fruits

Running the above code gives us the expected result ?

The first value in the array is apple

Command Injection Attack

Now imagine a malicious user calls the function with this parameter ?

print_array() {
    in_array=$1
    eval echo ""The first value in the array is \${$in_array[0]}""
}

fruits=(apple orange grapes berry)
print_array 'x}"; cal; #'

Running the above code gives us this dangerous result ?

The first value in the array is
   December 2023
Su Mo Tu We Th Fr Sa
                1  2
 3  4  5  6  7  8  9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

The user completely bypassed the intended functionality and executed the cal command. This could be devastating if they used commands like rm -rf * instead.

Safe Alternatives to eval

Here are secure alternatives to eval for common use cases ?

Using Arrays and Parameter Expansion

Instead of eval, use proper array handling ?

print_array() {
    local -n array_ref=$1
    echo "The first value in the array is ${array_ref[0]}"
}

fruits=(apple orange grapes berry)
print_array fruits

Using printf for Variable Names

For dynamic variable access, use printf with %q for safe quoting ?

safe_echo() {
    local var_name=$1
    printf "Variable %s contains: %q<br>" "$var_name" "${!var_name}"
}

Using Associative Arrays

Replace dynamic variable names with associative arrays ?

declare -A config
config[database_host]="localhost"
config[database_port]="5432"

echo "Host: ${config[database_host]}"

Key Security Guidelines

  • Never use eval with user input ? It's nearly impossible to sanitize safely
  • Use proper parameter expansion ? Bash provides many built-in features
  • Validate and sanitize all inputs ? Even when not using eval
  • Use arrays and nameref variables ? For dynamic data structures

Conclusion

Avoid eval due to command injection risks. Use arrays, parameter expansion, and proper quoting instead. When you must use eval, never pass user input directly to it.

Updated on: 2026-03-15T17:27:44+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements