Scalar
Two types of variables exist in the Korn shell. The first is a string; the second is a number. Of the numbers, two types are available: integers and floating-point. Most Korn shell implementations support integer numbers only. Korn shell 93, however, supports floating-point numbers. Integers are whole numbers, such as 14 and -999. Floating-points are numbers that can contain a fraction, such as 3.14159 or -99.54.
A scalar is your basic name-value pair that has been discussed in this book. A scalar has a varname and a value. That value can be accessed and assigned by the programmer, as is shown in the next two sections.
Accessing
To this point, the discussion has indicated that a variable has a value. The question therefore becomes, How do you access the value of the variable? Fortunately, the answer is simple. The dollar sign ($) preceding the variable name is used to access the value of the variable.
As an example, look at the following work that was done at the command line:
$ echo PS1 PS1 $ echo $PS1 $ # Displays the contents of PS1 which is the $
The command echo is used to show values. In the first line of the previous code, PS1 is echoed. Sure enough, the shell returns PS1. When the dollar sign is placed before the varname, $PS1, the shell returns the value associated with the variable PS1 (PS1 means prompt string number one).
Assigning
Assigning a value to a varname can be accomplished by placing an equal sign between the varname and the value. A space can't exist either before or after the equal sign. Although you might not have thought about it, you have already seen the assigning of variables in action when you looked at the .profile file in Chapter 1. Here are some examples from that file:
HISTSIZE=1000 HISTFILESIZE=1000
If a space is used in the value, the value must be placed within quotes, as seen in the following examples:
KSH_VERSION='@(#)PD KSH v5.2.14 99/07/13.2' PS1='$ '
More on quoting is discussed in Chapter 5, "Quoting." In the following example, three variables are defined as integers:
integer x=0 integer y=1000 integer Num=0
typeset
The typeset command is used to define variables. Many variables have aliases that are actually typeset commands. For example, integer, from the previous section, is an alias for typeset -i. The syntax for typeset is
typeset [+-AHlnprtux] [+-ELFRZi[n]] [name[=value]]
This command is used to set and unset attributes for variables, or to list the varnames and attributes of all variables.
Table 3.1 lists many commonly used attributes and their meanings. Note that not all of these are compatible with all versions of UNIX/Linux. Some of these are specific to Korn Shell 93. Check the man pages for your distribution of UNIX/Linux for a complete listing.
Table 3.1 Typeset attributes
Attribute |
Meaning |
- |
Used to set attributes after setting value(s) |
+ |
Used to unset attributes after setting values |
-A |
Associative array |
-E |
Exponential number; n specifies the significant digits |
-F |
Floating-point number; n specifies the number of decimal places (ksh 93) |
-i |
Integer; n specifies the arithmetic base |
-l |
Lowercase |
-L |
Left justifies; n specifies field width |
-LZ |
Left justifies and strips leading zeros; n specifies field width |
-n |
Name reference |
-p |
Displays variable names, attributes, and values of all variables |
-R |
Right justifies; n specifies field width |
-r |
Read-only |
-RZ |
Right justifies; n specifies field width and fills with leading zeros |
-u |
Uppercase |
-x |
Export |
-Z |
Zero-filled; n specifies field width; same as -RZ |
Here are some examples using typeset. The first displays the names and attributes of all variables:
$ typeset p # Print typeset variables readonly HISTFILESIZE=1000 readonly HISTSIZE=1000 readonly HOME=/home/shell readonly HOSTCHAR=MOOSE readonly HOSTNAME=moose.net readonly IFS=' ' readonly INPUTRC=/etc/inputrc readonly KDEDIR=/usr readonly KSH_VERSION='@(#)PD KSH v5.2.14 99/07/13.2' readonly LANG=en_US readonly LC_ALL=en_US readonly LINES=53 readonly LINGUAS=en_US readonly LOGNAME=shell readonly MAIL=/var/spool/mail/shell readonly MAILCHECK=600 readonly OPTIND=1 readonly PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/shell:/home/ shell/bin:/usr/X11R6/bin readonly PPID=28568 readonly PS1='$ ' readonly PS2='> ' readonly PS3='#? ' readonly PS4='+ ' readonly PWD=/home/shell readonly QTDIR=/usr/lib/qt-2.0.1 readonly RANDOM=5837 readonly SECONDS=13191 readonly SHELL=/bin/ksh readonly TERM=vt100 readonly TMOUT=0 readonly USER=shell readonly _=-p readonly kdepath=/usr/bin
The next two examples show initializing and assigning values to two new variables:
$ typeset Program=$0 $ typeset host='hostname'
The following example (note, this does not work in Linux or any ksh earlier than 93 because they do not recognize the -F attribute) makes salary a floating-point variable that prints two spaces after the decimal point:
$ typeset -F2 salary
Throughout this book, if an alias for a typeset is available, it usually is used because it is easier to remember (and tends to be a little more cross-platform friendly).
Four Common Errors
You should watch out for four common errors when assigning and accessing variables. These errors do not necessarily produce syntax errors, which makes them an even worse enemy.
The first common error is accessing the variable incorrectly. The following example shows this error:
$ WIFE=Dana $ echo $WIFE Dana $ $WIFE=Computer ksh: Dana=Computer: not found
More than likely, the previous example is an attempt to set the varname WIFE equal to Computer. However, with the dollar sign there, the shell returns the value of WIFE and is left with Dana=Computer, which is not correct. If the value of WIFE were not previously set, a slightly different error would occur, as shown in the next example:
$ $WIFE=Dana ksh: =Dana: not found
The second common error is in not having the dollar sign. The following example shows this error, which is the same error shown previously in the chapter:
$ echo PS1 PS1
In this example, the user is trying to access the value associated with the varname PS1. By not having the dollar sign, it returns the string PS1 instead of the value of PS1. This type of error is much more difficult to catch because no error occurs from the computer's perspective; it just did what the programmer told it to do.
The third common error is assigning a variable that has been previously defined. This is an error despite the fact that it works. This one, similar to the previous one, falls into the category of the computer doing what you said, and not what you meant. The following code shows an example of this:
$ cat assigning #!/bin/ksh x=4 y=10 while [ $x -le $y ] do echo $x ((x=x+1)) if [ $x -eq $y ] then ((x=4)) fi done
This code, although syntactically accurate, is an endless loop because reassigning x means that whenever x becomes equal to y, its value is reset to 4:
$ assigning 4 5 6 7 8 9 4 5 6 7 8 9 4 5 6 7 (This continues ad infinitum or until Ctrl+C is pressed!)
Finally, the fourth common error that a programmer can make is assigning a variable if that variable is not previously defined. A small modification to the previous script accomplishes this. The modification has been bolded to make it easier to find:
#!/bin/ksh x=4 y=10 while [ $x -le $y ] do echo $x ((x=x+1)) if [ $x -eq $y ] then ((x=z)) fi done
The change is that when x equals y, x is set to z. Unfortunately, z has not been previously defined. The question therefore is what happens when the program is executed? The following code shows the result:
$ assigning 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 (This continues ad infintum or until Ctrl+C is pressed!)
The shell automatically sets the undefined z to have a value of zero. Notice that the script will still run forever and that no error is ever produced.