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)
i.e.
$ 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
29
#Now to add the values of 'offsetno' with 'total number of .sh files' in my directory
$ expr $offsetno + `ls /tmp/mydir/*.sh | wc -l`
38
#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``
Output:
expr: syntax error
64
#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
38
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.
Subscribe to:
Post Comments (Atom)
© Jadu Saikia www.UNIXCL.com
10 comments:
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.
@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)
i.e.
var=$(expr $(date '+%m') + 1)
works
but
var=`expr `date '+%m'` + 1`
does not work.
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html explains this in details.
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.
I have a script with
function myfunc {
echo in myfunc
}
# i want to evaluate another script and pass in "myfunc"
# e.g.
x=`. otherscript.sh myfunc`
if I don't use the backticks myfunc is found and called. Is there a way to assign x above?
#I have a script with:
function myfunc {
echo in myfunc
}
x=`. otherscript.sh myfunc`
#above assignment of x fails
#but this below works
. otherscript.sh myfunc
is there a way to get the x assignment to work? At runtime I get "myfunc: command not found"
@Paul,
do you mean this ?
$ cat p.sh
#!/bin/sh
_myfunc () {
echo $1 + 100 | bc
}
_myfunc $(sh q.sh 9)
$ cat q.sh
#!/bin/sh
val=$1
echo $((s=val+5))
$ sh p.sh
114
Please let me know if you have any other queries. Thanks for your comment.
Hi,
Im trying to do something like this:
#!/bin/bash
test="{33,351}";
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?
Thanks
@Edu,
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
do
...
done
or
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
do
ls -laht /tmp/_structure/interface*_${test}_*.xml
done
Please let me know if I misunderstood your query. Thanks.
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.
@Subhan,
Putting on .bash_profile
d() {
date
}
should print the current time.
Post a Comment