Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [209]

By Root 977 0
when ksh93 is compiled from source code. bash always enables it.

Indexed Arrays

Both ksh93 and bash provide an indexed array facility that, while useful, is much more limited than analogous features in conventional programming languages. In particular, indexed arrays can be only one-dimensional (i.e., no arrays of arrays). Indexes start at 0. Furthermore, they may be any arithmetic expression: the shells automatically evaluate the expression to yield the index.

There are three ways to assign values to elements of an array. The first is the most intuitive: you can use the standard shell variable assignment syntax with the array index in brackets ([ ]). For example:

nicknames[2]=bob

nicknames[3]=ed

puts the values bob and ed into the elements of the array nicknames with indices 2 and 3, respectively. As with regular shell variables, values assigned to array elements are treated as character strings.

The second way to assign values to an array is with a variant of the set statement. The statement:

set -A aname val1 val2 val3 ...

creates the array aname (if it doesn't already exist) and assigns val1 to aname[0], val2 to aname[1], etc. As you would guess, this is more convenient for loading up an array with an initial set of values. This was the first mechanism added to ksh for assigning multiple array elements in one operation, and we mention it primarily so that you'll recognize it if you see it in an existing script.

* * *

Tip


bash doesn't support set -A.

* * *

The third (recommended) way is to use the compound assignment form:

aname=(val1 val2 val3)

To extract a value from an array, use the syntax ${ aname [ i ]}. For example, ${nicknames[2]} has the value bob. The index i can be an arithmetic expression. If you use * or @ in place of the index, the value will be all elements, separated by spaces. Omitting the index ($nicknames) is the same as specifying index 0 (${nicknames[0]}).

Now we come to the somewhat unusual aspect of arrays. Assume that the only values assigned to nicknames are the two that we saw earlier. If you type echo "${nicknames[*]}", you will see the output:

bob ed

In other words, nicknames[0] and nicknames[1] don't exist. Furthermore, if you were to type:

nicknames[9]=pete

nicknames[31]=ralph

and then type echo "${nicknames[*]}", the output would look like this:

bob ed pete ralph

This is why we said the elements of nicknames with indices 2 and 3 earlier, instead of the second and third elements of nicknames. Any array elements with unassigned values just don't exist; if you try to access their values, you get null strings.

You can preserve whatever whitespace you put in your array elements by using "${ aname [@]}" (with the double quotes) rather than ${ aname [*]}, just as you can with "$@" rather than $* or "$*".

Both shells provide an operator that tells you how many elements an array has defined: ${# aname [*]}. Thus, ${#nicknames[*]} has the value 4. Note that you need the [*] because the name of the array alone is interpreted as the 0th element. This means, for example, that ${#nicknames} equals the length of nicknames[0]. Since nicknames[0] doesn't exist, the value of ${#nicknames} is 0, the length of the null string.

You can think of an array as a mathematical function that takes an integer input parameter and returns a corresponding value (the element at that number). If you do so, then you can see why arrays are "number-dominated" data structures. Because shell programming tasks are much more often oriented toward character strings and text than toward numbers, the indexed array facility isn't as broadly useful as it might first appear.

Nevertheless, we can find useful things to do with indexed arrays. For example, here is a cleaner solution to the problem we presented earlier, in Section 14.3.1, in which a user can select a terminal type (TERM environment variable) at login time. Example 14-2 presented the user-friendly version of this code that used select and a case statement.

We can eliminate the entire case construct by taking

Return Main Page Previous Page Next Page

®Online Book Reader