Project87.Scripting Tips


Project 87. Scripting Tips

"How do I write a function that returns an array of values?"

This project presents several tips that you might find useful when writing Bash shell scripts. It shows you how to declare variables and arrays, perform integer arithmetic, test if a value is numeric, return values from functions, and implement variable variables.

Tip

Display the names of all integer variables by typing

$ declare -i


To learn more about the declare command, type

$ help declare



Declare Your Variables

This tip has nothing to do with the red channel at Customs. Declaring a variable is a way of telling Bash more about how you are going to use the variable. To declare a variable, use the Bash built-in command declare, followed by a type and variable name. Variable types include integer and array, both of which are described at greater length in this project.

In the next example, we declare the variable count to be an integer variable and perform some simple integer arithmetic, setting and incrementing count. First, by way of comparison, we try the sequence with an undeclared variable, which is taken by Bash to be a general-purpose string variable.

$ s=1 $ s=s+1 $ echo $s s+1 $ declare -i count=1 $ count=count+1 $ echo $count 2


You may also declare variables read-only and export them as environment variables.

Bash lets you declare a variable to be an array. An array variable holds many values, each accessed by its ordinal number (index). The following examples illustrate this.

Declare an array, and initialize it by specifying the option -a and listing the values you wish to assign within parentheses, separated by spaces. Enclose in double quotes any values that contain spaces.

$ declare -a products $ products=(iBook iMac PowerBook PowerMac ¬     "iPod shuffle" AirPort)


To retrieve a particular value, expand the array variable name, employing the syntax

${array-variable-name[index]}


To display the first value, which has an index of 0, and the fifth value, which has an index of 4, type

$ echo ${products[0]} iBook $ echo ${products[4]} iPod shuffle


Display all values by giving an index of star.

$ echo ${products[*]} iBook iMac PowerBook PowerMac iPod shuffle AirPort


To display the number of values in the array, type

$ echo ${#products[*]} 6


To display the length, in characters, of the second value in the array, type

$ echo ${#products[1]} 4


To create a list of all values, use a for loop to list all values one at a time.

$ for p in "${products[@]}"; do echo $p; done iBook ... iPod shuffle AirPort $


Enclosing the expansion in double quotes, and using an index @ (instead of *), ensures that each value is expanded to preserve spaces; without this, iPod shuffle expands into two values.

Learn More

The difference between @ and * used as an array index affects expansion of the array in the same way that it affects expansion of positional parameters, explained in "Basic Expansion" in Project 76.


Use Integer Arithmetic Expressions

Bash provides a special syntax for integer arithmetic expressions and comparisons, in which variables are automatically expanded and assumed to have the type integer. Expressions are enclosed within $((...)), and conditions, within ((...)). Within the double parentheses, you may employ expressions very much like those of the C programming language.

Tip

Learn about the Bash arithmetic expression allowed within ((...)) and $((...)) by typing /^ARITHMETIC EVALUATION within the Bash man page.


Here are a couple of examples.

$ i=7; j=35 $ echo $((i+j)) 42 $ if (((i*j) == 245)); then echo "yes"; fi yes


As a trivial example, we might offer a thousand greetings in the following manner.

$ a=1000; while ((a!=0)); do echo -n "*hello*"; ¬     ((a--)); done


Test for a Numeric Value

Here's a handy tip to determine whether a value is numeric. The line beginning with read generates a prompt, (Give a number) and assigns whatever you type to variable num. The line beginning with if tests num to see whether it's numeric.

$ read -p "Give a number: " num Give a number: i23 $ if [ "${num//[0-9]/}" ]; then echo "Not numeric"; fi Not numeric $ read -p "Give a number: " num Give a number: 123 $ if [ "${num//[0-9]/}" ]; then echo "Not numeric"; fi


Project 76 explains the parameter extension techniques we used in this trick.

Return Arbitrary Values

A Bash shell script or function may return an exit condition of 0 to 255, which is available in the shell special variable $?. To return an arbitrary value, we use the following trick, shown here applied to a Bash function.

The function return-eg returns a string value, simply set to Janet, to illustrate the technique. The function echoes its return value, and the calling script captures that value by calling the function and enclosing it in $(...). This syntax tells Bash to execute the function and replace it with its own output; thus, we assign the return value to the variable name.

$ cat return-eg return-eg () {   # processing here   result="Janet"   echo $result } name=$(return-eg) echo $name $ ./return-eg Janet


Learn More

Project 52 covers Bash functions.


If we combine the arbitrary-value trick with Bash array variables, we can write and call a function that returns many values.

$ cat return-eg return-eg () {   # processing here   result="Janet Sophie"   echo $result } declare -a guests guests=($(return-eg)) for ((i=0; i<${#guests[*]}; i++)); do   echo "guest $((i+1)) ${guests[i]}" done $ ./return-eg guest 1 Janet guest 2 Sophie


Variable Variables

Languages such as PHP implement variable variables. If you know what they are and would like to simulate their functionality in Bash, this trick is for you. Here's an example in which we echo the value of the variable detailsJanet.

$ echo $detailsJanet Name: Janet Forbes, Country: England


Now we try the same exercise, except that the Janet part of the variable is itself held in a variable and, naturally, could be anything.

$ read -p "Give name: " name Give name: Janet $ eval "echo \$details$name" Name: Janet Forbes, Country: England


The built-in eval command tells Bash to expand the quoted command sequence and then to execute the expanded text as though it were the original command. The net effect is to expand the line twice before it's executed. After eval is executed, the command sequence in the example above becomes

echo $detailsJanet


Then this command is executed in the normal manner. If you were to give a different name, such as Sophie, in response to the Give name: prompt, the final statement would evaluate to

echo $detailsSophie





Mac OS X UNIX 101 Byte-Sized Projects
Mac OS X Unix 101 Byte-Sized Projects
ISBN: 0321374118
EAN: 2147483647
Year: 2003
Pages: 153
Authors: Adrian Mayo

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net