Reputation: 79
I want to be able to modify the value of the variable used in a for-in loop, from inside the loop.
#!/bin/bash
for i in {1..100}
do
((i--))
done;
Why is this loop not an infinite-loop? How can it be so?
Upvotes: 0
Views: 1350
Reputation: 4704
The for in
loop in shell is not numeric, instead it works on a list of strings that is generated from the next token/construct after in
and stored in memory. The indicated [control] variable takes the values from the list, one after another in each iteration; there is no way to manipulate that list. You can modify the variable inside the loop, ok, but at the next iteration it will get the next value of the list.
In other words, the control variable is not a control variable, it's only a placeholder to refer to the current items of the list (better: it does not "refer", it contains a copy of the referred item).
This means that the number of iterations is predetermined once, when the list of string is created. The number of iterations is equal to the number of strings in the list (of course you can break inside the loop).
Other languages have similar constructs, like for each ...
, or using iterators and so on.
The real thing about for
can be explained with the following example:
for a in *
do echo $a
done
is really interpreted as
for a in file1 file2 file3 file4 ie all the files in current directory
....
as is in fact perfectly legal to write
for a in 1 2 3 4 A B C D
...
Last note. I said the list of a for
is kept in memory. I opened two terminals, launched a for
in one, at checked the memory consumption in the other using free(1).
for a in 1 2 3; do sleep 50; done
...gives...
total used free shared buffers cached
Mem: 246596 224712 21884 0 33948 71584
for a in $(seq 1 1000000); do sleep 50; done
...gives...
total used free shared buffers cached
Mem: 246596 242864 3732 0 8400 24668
(notice the drop of buffers from 33948 to 8400, and the cached from 71584 to 24668). Finally ask for ten times more:
for a in $(seq 1 10000000); do sleep 50; done
...gives...
total used free shared buffers cached
Mem: 246596 243492 3104 0 688 8700
(more drop of buffers). The kernel is trying to find more memory and, doing that, slows down the poor little computer!
This shell for
is very nice and powerful, but beware of the length of the list.
Upvotes: 1
Reputation: 2691
Because it is not a C-style loop. The condition to exit the loop is not anyhow related to the value of i
. It will just loop over the range from 1 to 100 and that's about it.
You can use C-style for-loop in bash if you have to:
for ((i=1; x<=100; i++)); do
((i--))
done
Upvotes: 2