sections in this module City College of San Francisco - CS160B
Unix/Linux Shell Scripting
Module: Scripting Basics1
module list

Variables and Arithmetic

When you create a variable it is local to the current shell. If you start a new process, the new process does not know the variable even exists. 

A subset of your variables are copied to child processes when they are started. These variables are called environment variables

You can place any variable in the environment by exporting it. Once a variable is in the environment, it remains there for your shell and all of its descendents. The only way you can remove a variable from the environment is to delete it (using unset) and recreate it.

A child process cannot alter the value of its parent's variables,  no matter whether they are local variables or environment variables.

As far as your code is concerned, there is no difference between a local and an environment variable. The only difference is whether a child process gets a copy when it starts:

$ cat showname
#!/bin/bash
echo "the value of \$Name is '$Name'"
$ Name=Greg
$ ./showname
the value of $Name is ''
$ export Name
$ ./showname
the value of $Name is 'Greg'
$

Note that Name is not a global variable. If showname modified the value of Name it would only affect the copy in showname, not the copy in the parent shell. Environment variables are just used to initialize variables for child processes.

Environment variables are normally used to hold constant system information that may be needed by a shell program. Variable data that must be provided to a shell program are usually passed in arguments.

Substituting variable's values

As indicated in your text, the full syntax for substituting the value of variable FOO is ${FOO}. If there is no ambiguity about where the name of the variable starts and ends, you can abbreviate this to $FOO

Remember, substitutions are performed before the final command is run. Consider the following command

echo "My name is $FIRST $LAST"

First, the $FIRST and $LAST are replaced by their values. If FIRST is Greg and LAST is Boyd, the resulting command looks like this

echo "My name is Greg Boyd"

Then the resulting command is run.

What would happen if the command had looked like this:

$FIRST $LAST

Try it.

Operators on variables

The ${} construct has a host of operators to operate on the variable's value during the substitution. We will cover the most basic ones here, and cover the pattern matching operators much later, as they can be quite confusing:

thisis substituted for
the value of the variable FOO${FOO}
the length (in characters) of the value of the variable FOO${#FOO}
the value of the variable FOO if it is non-empty.
If the value of FOO is empty, it aborts the shell script and prints the message on standard error.
${FOO:?message}
the value of the variable FOO if it is non-empty. If the value of FOO is empty, it is replaced by alternate. The value of FOO is not modified, however. (It would be left empty.)${FOO:-alternate}
the value of the variable FOO if it is non-empty. If the value of FOO is empty, it is replaced by alternate. The value of FOO is also set to alternate.${FOO:=alternate}

Examples:

$ FOO=hello
$ echo ${#FOO}
5

$ FOO=

$ echo ${FOO}

$ echo ${FOO:?"help, where is FOO?"}
bash: FOO: help, where is FOO?
$
$ echo ${FOO:-"FOO was empty"}
FOO was empty
$ echo $FOO

$ echo ${FOO:="FOO was empty"}
FOO was empty
$ echo $FOO
FOO was empty
$

Arithmetic

The external command expr can be used for shell arithmetic. Unfortunately, many of the arithmetic operators are also special characters in the shell. Consider the following simple expression, where num1 and num2 are integers:

(num1 + num2) * num1

This could be understood by expr if spaces were used appropriately:

( $num1 + $num2 ) * $num1

However, the parenthesis and the asterisk are special characters to the shell, so they must be escaped. The final command is 

expr \( $num1 + $num2 \) \* $num1

You can see how ugly this could get.

The double parenthesis operator was introduced in POSIX-compliant shells to simplify arithmetic operations. Simply take any C-style arithmetic statement and enclose it in double parenthesis. The following syntax restrictions are relaxed

Arithmetic can appear in two forms: (( )) by itself, or $(( ))

Examples:

The following examples all compute num1 = num1 * (num1+num2)

(( num1 = num1 * (num1 + num2)))

num1=$((num1 * (num1 + num2)))

(( num1 = $num1* ($num1+$num2)))

(( num1 *=(num1+num2)))

Note that shell arithmetic is integer arithmetic. For example

echo $(( 3 / 2 ))

1

Common Variables

Your shell process has many variables defined. Most of these are envionment variables. A few of the most commonly-used ones are below:

variableenv?meaningvariableenv?meaning
HISTFILENpath to history fileIFSNdelimiter characters for second tokenization of shell commands
HISTSIZENnumber of commands in historyHOMEYhome directory path. You should never change the value of HOME. The shell uses it for ~ and the cd command.
LOGNAMEYyour login namePATHYlist of directories to look in to find commands
PS1, PS2, etcNprompt stringsPWDYpath to current directory
SHELLYpath to shellTERMYtype of terminal (for cursor addressing)

Prompt Strings

PS1, etc, are your prompt strings. Prompt strings are evaluated to output the prompt. There are three prompt strings, but the last one (PS3) is rarely seen.

PS1 is output as your primary prompt. PS2 is output when you enter a command and it is incomplete when you type newline:

-bash$ VAR="hello there. how are
> you"
-bash$

In the example above, the primary prompt is "-bash$ "  The secondary prompt is "> ". We can prove this by setting these variables:

PS1="another command? "

PS2="finish it, silly> "

After defining this, here is our example:

another command? VAR="hello there, how
finish it, silly> are you?"
another command?

Since prompt strings are evaluated when the prompt is output, you can place commands and variables in them. However, this is when you must understand the word evaluated, and how understanding quoting rules can be important. (We will go over quoting rules in the next module. You may want to refer back to this section.)

Suppose you want to output the path to the current directory in your prompt string. To do this we will simply refer to our PWD variable from within our prompt string. Notice how the type of quotes we use affects how our prompt works:

$ pwd
/users/gboyd
$ PS1="[$PWD]$ "
[/users/gboyd]$ cd /tmp
[/users/gboyd]$ pwd
/tmp
[/users/gboyd]$
$ pwd
/users/gboyd
$ PS1='[$PWD]$ '
[/users/gboyd]$ cd /tmp
[/tmp]$ pwd
/tmp
[/tmp]$

The difference is due to when the $PWD variable gets evaluated and the result substituted. When it is enclosed in double-quotes, the value of $PWD is substituted when the prompt is set. This places a constant path in the prompt string. When it is enclosed in single-quotes, the prompt string contains the string [$PWD]$  When the prompt is evaluated, the current value of $PWD is substituted and the result output.

Customization of prompt strings in bash is simple through the use of special prompt string escape sequences. Some of the most popular ones are

\h, \H   -  hostname (short and long formats)

\t, \T, \@, \A - time formats

\w, \W  - full and basename of the current working directory

\u  - current user name

\s - shell name

For example, PS1='[\u@\h]<\W>(\A)$ ' gives the prompt

[gboyd@hills]<~>(17:11)$ 

You should always place a space at the end of your prompt string for clarity.

Other notes on standard variables

TERM - This is your terminal type.  Terminal types are mostly legacy code. A value of vt100 will usually get your terminal working if it isn't set. Remember, TERM must be an envionment variable, so you must use export if you create it.

PATH - This is your search path. It is a colon-separated list of directories to look in to find commands. If you modify your search path, make sure you only append to it. For example, if you have your own directory /home/you01/bin that you place your shell scripts in and you want it to be able to run your shell scripts by just typing their name, add your directory to the end of your search path like this:

PATH=$PATH:/home/you01/bin

(You should never place a personal directory at the front of your search path!)

Preview question: After reading your text, can you describe situations where each type of quoting might be used: single-quotes, double-quotes or the backslash?

Prev This page was made entirely with free software on linux:  
Kompozer
and Openoffice.org    
Next

Copyright 2009 Greg Boyd - All Rights Reserved.

Document made with Kompozer