Is there any difference in bash between using `eval $cmd` and just `$cmd`?

In bash, you can treat a string as command (and run it) in two different ways:

cmd="echo -n sometext"
eval $cmd    # Not sure if quotes make a difference here


cmd="echo -n sometext"
$cmd    # Not sure if quotes make a difference here either

Is there any difference between the two? Is there a situation where quotes around cmd make a difference? What about performance?

1 answer

  • answered 2018-03-11 12:41 Samit

    Yes, there is a difference :) You need to first understand how eval works. Basically, eval is a shell builtin command. Whatever argument passed to eval is first treated as a string. Let's take below example:

     cmd="echo -n sometext"
     eval $cmd 

    The complete run process of this command is as follows:

     eval $cmd
     + eval echo -n sometext
     ++ echo -n sometext

    Here, first $cmd first got evaluated and then the whole string was passed to eval command as argument. Then eval evaluates the command considering the first argument as a "command or an executable file" and then run as a normal command. So, here there is 2 rounds of evaluation getting performed for the execution of the complete command. (NOTE: The + symbol above shows the step wise execution when used in bash -x mode)

    The main consequence lies in variable expansion. With eval we have two rounds of expansion. One of course, when cmd is defined, and one when eval is executed.

    cmd="echo -n $var \$var"
    var="chanded in the mean time"
    eval $cmd
    inital chanded in the mean time

    However, when you use $cmd only without eval, bash takes care of everything from variable expansion to the final execution. Just see the debugging window details while running only $cmd

    + echo -n sometext

    Performance wise, direct use of $cmd is good enough. However, when you are trying to use some external command or a script which requires environment changes, you can use eval

    In cmd="echo -n sometext", quotes are necessary, otherwise after "echo", bash will raise an error like below:

    cmd=echo -n sometext
    -n: command not found

    I hope the explanation will be helpful.