Can someone explain the difference between these two code blocks? I would think Block #2 would output the same as Block #1 but it does not. Can someone explain why?
# ./arguments.sh hello my name is X
Block #1
for i
do
echo $i
done
Output:
hello
my
name
is
X
Block #2
args=$#
for (( i=1; i<=$args; i+=1 ))
do
echo $i
done
Output:
1
2
3
4
5
Best Answer
roaima's answer answers the question that you actually asked:
... although I presume that you would have figured that much out for yourself in another six to eight minutes — it's kind-of obvious. You probably want the second program to do something like
to display the argument that is indexed by the number that is stored in variable
i
(and referenced as$i
). As noted in the comment, that doesn't do what you want. (It does do something; I encourage you to experiment and figure out what it does.) But this is close to something that does work:or, equivalently,
These commands
i
(one of the numbers 1, 2, 3, ...)$
in front of it, forming$1
,$2
,$3
, etc.eval
command to say, "take this command line that I've just constructed, and evaluate it as if I had typed it.So that would have the effect of executing
But, as the comments suggest, you should try to avoid this.
eval
can be dangerous if the input is anything other than plain words. Search this site; you'll find plenty of explanations of that.But there is a fairly safe way to get the second program to do the same thing the first one does: change
to
OK, first of all,
${i}
is pretty much the same as$i
. The!
gives you an effect similar to that of theeval
command —${!x}
looks up the value ofx
(i.e.,$x
or${x}
) and uses that as the name of the variable to look up. So, ifx=foo
, then${!x}
is the same as$foo
. The above code does the same thing withi
, fetching the parameter whose name is the value ofi
.By the way, you should always quote all references to shell variables (e.g.,
"$i"
,"$#"
,"$args"
,"${i}"
and"${!i}"
) unless you have a good reason not to, and you’re sure you know what you’re doing.