Working with Variables


You can create variables in your scripts to save information. These work just like the shell variables described in Chapter 4. You can set or access a variable like this:

 MESSAGE="Hello, world" echo $MESSAGE

Recall that echo prints its arguments to standard output. The section “Shell Input and Output” will explain more about printing to the screen.

You need the $ in $MESSAGE if you want to print the value. The line echo MESSAGE will just print the word “MESSAGE”. This is different from languages like C, which do not require a $ when printing a variable, and also from Perl, which always requires a $ or other symbol in front of variable names.

You can also use your shell environment variables in your scripts. For example, you might want to create a script that configures your environment for a special project, like this:

 $ cat dev-config DEVPATH=/usr/project2.0/bin:/usr/project2.0/tools/bin:$HOME/dev/project2.0 export DEVPATH cd $HOME/dev/proj ect2.0

This script uses the value of the shell environment variable $HOME. It also sets a new variable, called DEVPATH. If you want DEVPATH to become a new environment variable, and the cd command to change your current directory, you will have to run the script in the current shell, like this:

 $ . ./dev-config

You can use environment variables to pass information to your scripts, as in this example, which uses the environment variable ARTICLE to pass information to the proof script we saw earlier:

 $ cat proof cat $ARTICLE | tbl | nroff -cm -rA2 \ -rN2 -rE1 -rC3 -rL66 -rW67 -rO0 | col | lp -dpr2 $ export ARTICLE=article2 $ ./proof

A better way to get information to your scripts is with command-line arguments, which will be explained later in this chapter. Alternatively, you can get input directly from the user with read, which is discussed in the section “Shell Input and Output.”

Special Variable Expansions

When the shell interprets or expands the value of a variable, it replaces the variable with its value. You can perform a number of operations on variables as part of their expansion. These include specifying a default value and providing error messages for unset variables.

Grouping Variable Names

While $VARNAME is usually more convenient, you can also get the value of a variable with ${VARNAME}. This can be useful when you want to concatenate the variable with other information. For example,

 NEWFILE=$OLDFILExxx

will set NEWFILE to the value of the variable OLDFILExxx. Since this variable probably doesn’t exist, NEWFILE will be empty Instead, you can use

 NEWFILE=${OLDFILE}XXX

which will set NEWFILE to the value of OLDFILE with “xxx” added on to the end.

Providing Default Values

At times you may want to use a variable without knowing whether or not it has been set. You can specify a default value for the variable with this construct:

 ${VARIABLE:-default}

This will use the value of VARIABLE if it is defined, and the string default if it is not. It does not set or change the variable.

For example, in the proof script shown earlier, the environment variable ARTICLE might not be defined. If you replace $ARTICLE as shown,

 cat ${ARTICLE:-article} | tbl | nroff -cm -rA2 \ -rN2 -rE1 -rC3 -rL66 -rW67 -rO0 | col | lp -dpr2

the script will format and print the file article by default when ARTICLE is undefined.

A related operation assigns a default to an unset variable. The syntax for this is

 ${VARIABLE:=value}

If VARIABLE is null or unset, it is set to value. If it already has a value, it is not changed.

Giving an Error Message for a Missing Value

Occasionally, you may not want a shell program to execute unless all of the important parameters are set. For example, a program may have to look in various directories specified by your PATH to find important programs. If the value of PATH is not available to the shell, execution should stop. You can use the form

 ${VARIABLE:?message}

to do this. When VARIABLE is not set, this will print message and exit. For example,

 echo ${PATH:?warning: PATH not set}

will print the value of the PATH variable if it is set. If PATH is not defined, the script exits with an error, and the message “warning: PATH not set” is printed to standard error.

If you do not specify an error message, as in,

 ${PATH:?}

a generic message will be displayed, such as

 sh: PATH: parameter null or not set

In the variable expansion examples just presented, the colon (:) and curly braces ({}) are optional. It is a good idea, however, to always make a point of using them, since they help make your scripts more readable and can prevent certain bugs.

Special Variables for Shell Programs

The shell provides a number of special variables that are useful in scripts. These provide information about aspects of your environment that may be important in shell programs. The shell also uses special variables, including the values $* and $#, to pass command-line arguments to your scripts. These variables will be discussed in a later section.

The variable ? is the value returned by the most recent command. When a command executes, it returns a number to the shell. This number indicates whether it succeeded (ran to completion) or failed (encountered an error). By convention, 0 is returned by a successful command, and a nonzero value is returned when a command fails. In the section “Conditional Execution,” you will learn how to test whether the last command was successful by checking $?.

The variable $ contains the process ID of the current process (the shell that is running your script). This can be used to create a temporary file with a unique name. For example, suppose you write a script that uses the find command, which often prints messages to standard error. You might want to capture the error messages in a file rather than printing them on the screen, but you need to pick a filename that does not already exist. You could use this command:

 find . -name $FILENAME > error$$

The value $$ is the number of the current process, and the filename error$$ is most likely unique.

The variable ! contains the process ID of the last background process. It is useful when a script needs to kill a background process it has previously begun.

Remember that NAME is the name of a shell variable, but $NAME is the value of the variable. Therefore, $, ?, and ! are variables, but $$, $?, and $! are their values.

The Korn shell and bash add the following useful variables. These are not standard in sh.

  • PWD contains the name of the current working directory.

  • OLDPWD contains the name of the preceding working directory.

  • LINENO is the current line number in your script.

  • RANDOM contains a random integer, taken from a uniform distribution over the range from 0 to 32,767. The value of RANDOM changes each time it is accessed.

Arrays and Lists

The Korn shell and bash allow you to define arrays. An array is a list of values, in which each element has a number, or index, associated with it. The first element in an array has index 0. For example, the following defines an array FILE consisting of three items:

 FILE[0]=new FILE[1]=temp FILE[2] =$BACKUP

The first element in FILE is the string “new”. The last element is the value $BACKUP. To print an element, you could enter

 echo ${FILE [2]}

You can also create arrays from a list of values. A list is contained in parentheses, like this:

 NUMBERS=(1 2 3 4 5)

To print all the values in an array, use * for the index:

 echo ${NUMBERS[*]}

Working with Strings

ksh and bash include several operators for working with strings of text. To find the length of a variable (the number of characters it contains), use the ${#VARIABLE} construct. For example,

 $ FILENAME="firefly.sh" $ echo ${#FILENAME} 10

The construct ${VARIABLE%wildcard} removes anything matching the pattern wildcard from the end (right side) of $VARIABLE. The pattern can include the shell wildcards described in Chapter 4, including * to stand for any string of characters. For example,

 $ echo ${FILENAME%.*} firefly

uses the wildcard .* to match the extension .sh, so echo prints the first part of the filename. The variable FILENAME is not modified.

Similarly, the pound sign can be used to remove an initial substring. For example,

 $ echo ${FILENAME#*.} sh

In this case, the wildcard *. matches the string “firefly.”. Echo prints the remainder of the string, which is “sh”.




UNIX. The Complete Reference
UNIX: The Complete Reference, Second Edition (Complete Reference Series)
ISBN: 0072263369
EAN: 2147483647
Year: 2006
Pages: 316

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