Bash Features

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}
About these ads
This entry was posted in bash, openSUSE. Bookmark the permalink.

2 Responses to Bash Features

  1. 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

  2. Mike Henders says:

    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… ;)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s