The bash system shell is the most widely used one on linux systems. For most sysadmins, it is the tool of choice to do small administrative tasks. There are of course other shells, and I don’t want to tell if one or the other is better.
Even though it is so well known by many people, one can stumble over some interesting features from time to time. I used one of them to create the data in the recent post about Linux and Memory. The task was, to iterate over a number of different test cases, but also over different sizes for each test case. The first one is easy:
for r in 1 2 3 4 5 6 7 8; do ./memxfer -s 32M 100 $r; done
You could also write this somewhat shorter as:
for r in $(seq 1 8); do ./memxfer -s 32M 100 $r; done
My method of choice was using a not so well known bash feature:
for r in {1..8}; do ./memxfer -s 32M 100 $r; done
The next step would be, to also iterate over sizes. All the sizes I normally use in this benchmark are powers of two, and I definitely do not want to write down all these numbers manually. Therefore, these numbers had to be calculated while iterating over the sizes. This can be done like this:
for s in {0..16}; do ./memxfer -s $((1<<$s))k 100 1; done
Finally, after putting all together, the command looks like the following:
for r in {0..8}; do
for s in {0..16}; do
./memxfer -s $((1<<$s))k 100 $r
done
done
Now back to those interesting curling bracket lists. It is obviously a very short method to create sequences of numbers. But they can do even more. For example, try the following command:
echo hello{1..4}
The result is a combination of the list with the preceding string:
hello1 hello2 hello3 hello4
This can also be done with letters like in
echo hello{a..f}
and it is possible to combine several lists to get permutations or counting backwards:
echo {a..c}{11..13}{z..w}
Just try it yourself. It is quite a nice thing. One last note: Sometimes, you want to use numbers that normally have a different digit count. To get the same number of digits for all of the numbers, it is interesting to add a number of leading zeros. The resolution to this is straight forward:
echo {001..300}
Nice post …
Did you know you can also define the step size this way? And go backwards?
> echo {01..10..2}
01 03 05 07 09
> echo {10..1..-2}
10 8 6 4 2
Interesting tip(s)! I already knew about the basic “{}” expansion, but the leading-zero and step-size features were new to me. Thing is, I was positive that I had tried doing leading zeros at some time in the past, and had it fail. So I did a bit of experimenting, and found that in fact, these features were introduced at some point between versions 3.2.39 (from SuSE 11.1) and 4.1.7 (from SuSE 11.3), i.e., they don’t work on 3.2.39. One more reason to update…