Thursday, October 29, 2009

Variables








 

 










Variables



Like virtually all programming languages, the shell allows you to store values into variables. A shell variable begins with an alphabetic or underscore (_) character and is followed by zero or more alphanumeric or underscore characters.



To store a value inside a shell variable, you simply write the name of the variable, followed immediately by the equals sign =, followed immediately by the value you want to store in the variable:





variable=value



For example, to assign the value 1 to the shell variable count, you simply write





count=1



and to assign the value /users/steve/bin to the shell variable my_bin, you simply write





my_bin=/users/steve/bin



A few important points here. First, spaces are not permitted on either side of the equals sign. Keep that in mind, especially if you're in the good programming habit of inserting spaces around operators. In the shell language, you can't put those spaces in.



Second, unlike most other programming languages, the shell has no concept whatsoever of data types. Whenever you assign a value to a shell variable, no matter what it is, the shell simply interprets that value as a string of characters. So when you assigned 1 to the variable count previously, the shell simply stored the character 1 inside the variable count, making no observation whatsoever that an integer value was being stored in the variable.



If you're used to programming in a language such as C or Pascal, where all variables must be declared, you're in for another readjustment. Because the shell has no concept of data types, variables are not declared before they're used; they're simply assigned values when you want to use them.



As you'll see later in this chapter, the shell does support integer operations on shell variables that contain strings that are also valid numbers through special built-in operations.



Because the shell is an interpretive language, you can assign values to variables directly at your terminal:





$ count=1 Assign character 1 to count

$ my_bin=/users/steve/bin Assign /users/steve/bin to my_bin

$



So now that you know how to assign values to variables, what good is it? Glad you asked.



Displaying the Values of Variables



The echo command is used to display the value stored inside a shell variable. To do this, you simply write





echo $variable



The $ character is a special character to the shell. If a valid variable name follows the $, the shell takes this as an indication that the value stored inside that variable is to be substituted at that point. So, when you type





echo $count



the shell replaces $count with the value stored there; then it executes the echo command:





$ echo $count

1

$



Remember, the shell performs variable substitution before it executes the command (see Figure 5.1).



Figure 5.1. echo $count.





You can have the value of more than one variable substituted at a time:





$ echo $my_bin

/users/steve/bin

$ echo $my_bin $count

/users/steve/bin 1

$



In the second example, the shell substitutes the value of my_bin and count and then executes the echo command (see Figure 5.2).



Figure 5.2. �echo $my_bin $count.





The values of variables can be used anywhere on the command line, as the next examples illustrate:





$ ls $my_bin

mon

nu

testx

$ pwd Where are we?

/users/steve/documents/memos

$ cd $my_bin Change to my bin directory

$ pwd

/users/steve/bin

$ number=99

$ echo There are $number bottles of beer on the wall

There are 99 bottles of beer on the wall

$



Here are some more examples:





$ command=sort

$ $command names

Charlie

Emanuel

Fred

Lucy

Ralph

Tony

Tony

$ command=wc

$ option=-l

$ file=names

$ $command $option $file

7 names

$



So you see, even the name of a command can be stored inside a variable. Because the shell performs its substitution before determining the name of the program to execute and its arguments, it scans the line





$command $option $file



and turns it into





wc -l names



Then it executes wc, passing the two arguments -l and names.



Variables can even be assigned to other variables, as shown in the next example:





$ value1=10

$ value2=value1

$ echo $value2

value1 Didn't do that right

$ value2=$value1

$ echo $value2

10 That's better

$



Remember that a dollar sign must always be placed before the variable name whenever you want to use the value stored in that variable.



The Null Value



What do you think happens when you try to display the value of a variable that has no value assigned to it? Try it and see:





$ echo $nosuch Never assigned it a value



$



You don't get an error message. Did the echo command display anything at all? Let's see whether we can more precisely determine that:





$ echo :$nosuch: Surround its value with colons

::

$



So you see no characters were substituted by the shell for the value of nosuch.



A variable that contains no value is said to contain the null value. It is the default case for variables that you never store values in. When the shell performs its variable substitution, any values that are null are completely removed from the command line, without a trace:





$ wc $nosuch -l $nosuch $nosuch names

7 names

$



The shell scans the command line substituting the null value for the variable nosuch. After the scan is completed, the line effectively looks like this:





wc -l names



which explains why it works.



Sometimes you may want to explicitly set a variable null in a program. This can be done by simply assigning no value to the variable, as in





dataflag=



Alternatively, you can list two adjacent pairs of quotes after the =. So





dataflag=""



and





dataflag=''



both have the same effect of assigning the null value to dataflag. Be advised that the assignment





dataflag=" "



is not equivalent to the three previous ones because it assigns a single space character to dataflag; that's different from assigning no characters to it.



Filename Substitution and Variables



Here's a puzzle for you: If you type





x=*



will the shell store the character * into the variable x, or will it store the names of all the files in your current directory into the variable x? Let's try it out and see:





$ ls What files do we have?

addresses

intro

lotsaspaces

names

nu

numbers

phonebook

stat

$ x=*

$ echo $x

addresses intro lotsaspaces names nu numbers phonebook stat

$



There's a lot to be learned from this small example. Was the list of files stored into the variable x when





x=*



was executed, or did the shell do the substitution when





echo $x



was executed?



The answer is that the shell does not perform filename substitution when assigning values to variables. Therefore,





x=*



assigns the single character * to x. This means that the shell did the filename substitution when executing the echo command. In fact, the precise sequence of steps that occurred when





echo $x



was executed is as follows:





  1. The shell scanned the line, substituting * as the value of x.



  2. The shell rescanned the line, encountered the *, and then substituted the names of all files in the current directory.



  3. The shell initiated execution of echo, passing it the file list as arguments (see Figure 5.3).

    Figure 5.3. echo $x.







This order of evaluation is important. Remember, first the shell does variable substitution, then does filename substitution, and then parses the line into arguments.



The ${variable} Construct



Suppose that you have the name of a file stored in the variable filename. If you wanted to rename that file so that the new name was the same as the old, except with an X added to the end, your first impulse would be to type





mv $filename $filenameX



When the shell scans this command line, it substitutes the value of the variable filename and also the value of the variable filenameX. The shell thinks filenameX is the full name of the variable because it's composed entirely of valid variable name characters. To avoid this problem, you can delimit the end of the variable name by enclosing the entire name (but not the leading dollar sign) in a pair of curly braces, as in





${filename}X



This removes the ambiguity, and the mv command then works as desired:





mv $filename ${filename}X



Remember that the braces are necessary only if the last character of the variable name is followed by an alphanumeric character or an underscore.












     

     


    No comments: