con-f-use
con-f-use

Reputation: 4028

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:

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

and

#!/bin/bash
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?

Upvotes: 4

Views: 1499

Answers (1)

Samit
Samit

Reputation: 615

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
 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.

var="inital"
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

$cmd
+ echo -n sometext
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.

Upvotes: 3

Related Questions