Friday, January 30, 2009

Evaluate expression inside another evaluation - bash script

As we know, $( ) is used to to evaluate sub-expressions in bash shell (same as of back-tick in bash shell)


$ var=`/sbin/ifconfig | grep eth0`

is same as

$ var=$(/sbin/ifconfig | grep eth0)

Lets discuss an example to see the good use of $( ) in bash shell.

#Suppose 'offsetno' variable is set to 9
$ offsetno=9

#Number of *.sh files under my directory (/tmp/mydir) is 29
$ ls /tmp/mydir/*.sh | wc -l

#Now to add the values of 'offsetno' with 'total number of .sh files' in my directory
$ expr $offsetno + `ls /tmp/mydir/*.sh | wc -l`

#Now if you need to store this output value in a variable called 'eff_num_file'
$ eff_num_file=`expr $offsetno + `ls /tmp/mydir/*.sh | wc -l``

expr: syntax error

#Oh what happened!! Lets echo 'eff_num_file' variable content; alas!! nothing got evaluated and stored.

$ echo $eff_num_file

#Now try this way:
$ eff_num_file=$(expr $offsetno + $(ls /tmp/mydir/*.sh | wc -l))

#See whats stored in eff_num_file variable, correct!!
$ echo $eff_num_file

What we noticed here is that back-tick within back-tick does not work, whereas $( ) inside $( ) work.

** The above example is just an example to explain the trick.


Werner said...

Is the back tick depreciated? I write scripts date insert the date into the filename like so:

mv file.tar.gz "`date`".file.tar.gz

Is the $() a better way? Interesting article.

Unknown said...

@Werner, thanks for commenting. I dont feel back-tick is depreciated. $( ) is just another way of evaluation of expression in bash. For your example, the following two does the same

$ mv file.log "`date`".file.log
$ mv file.log "$(date)".file.log

** we are using "" as date output contains spaces.

The only advantage I saw is when we need to evaluate an expression inside another expression (As I explained above)


var=$(expr $(date '+%m') + 1)
var=`expr `date '+%m'` + 1`
does not work. explains this in details.

Unknown said...

One of my reader Peace,
notHerbert has pointed this

Nested backticks must be escaped to work.

var=`expr \`date '+%m'\` + 1`

Thanks Peace, its useful.

Unknown said...

I have a script with
function myfunc {
echo in myfunc

# i want to evaluate another script and pass in "myfunc"
# e.g.
x=`. myfunc`

if I don't use the backticks myfunc is found and called. Is there a way to assign x above?

Unknown said...

#I have a script with:

function myfunc {
echo in myfunc

x=`. myfunc`
#above assignment of x fails

#but this below works
. myfunc

is there a way to get the x assignment to work? At runtime I get "myfunc: command not found"

Unknown said...


do you mean this ?

$ cat

_myfunc () {
echo $1 + 100 | bc

_myfunc $(sh 9)

$ cat

echo $((s=val+5))

$ sh

Please let me know if you have any other queries. Thanks for your comment.

Edu said...


Im trying to do something like this:


ls -laht /tmp/_structure/interface*_${test}_*.xml

The problem is that the script recognizes the {33,351} like a string and not as a command. if i replace the var test for the static value it results well. But i need that it comes from a variable.

I've tried as an evaluation expression but it not works. Can you help me?

Unknown said...


Thanks for the comment.

Assuming you are trying to have test var to be from 33,34,35,....,351

you can use:
test=$(seq 33 351)

for i in $test


test=`seq 33 351`

And if you are just looking for test var to be one of two values viz. 33 and 351

you can loop using for:
for test in 33 351
ls -laht /tmp/_structure/interface*_${test}_*.xml

Please let me know if I misunderstood your query. Thanks.

Anonymous said...

Hi, I have a related question. Is it possible using $(), `` or similar mechanism to have an alias whose value is evaluated when called, not when assigned? Here's a simple example.
alias d = "echo `date`"
d will now print out the date at the time d was assigned
what I want to do is have d print out the current date when called. This is a simplistic example I know, but it is representative of what I need.

Unknown said...


Putting on .bash_profile

d() {

should print the current time.

© Jadu Saikia