BOURNE SHELL The following topics are discussed in this section:

GENERAL INFORMATION

The Bourne shell is an interactive command interpreter and command programming language. The shell carries out commands specified at the terminal or from a file. A more restricted form of the Bourne shell is called the restricted shell. The restricted shell is useful for installations that require a more controlled shell environment.

GETTING STARTED

Your default shell is executed automatically upon login by the login command or as a subshell under the login shell. The /etc/passwd file contains the default shell for each user. You can set your default login shell by using the chsh command after you have logged into your account. Once you are logged in, you can start a new Bourne shell (a subshell) by issuing the bsh or sh command at the OS prompt. To start a Restricted subshell, issue the rsh command.

The initial shell invoked by the login command executes commands found in the /etc/profile file and then in your $HOME/.profile file if one exists. The shell then accepts commands from either the command line or a file.

USING THE BOURNE SHELL

Executing Commands

When a command is issued in the bsh, the command is evaluated and all substitutions (variables and aliases) are made. If the evaluated command matches a bsh special command or a defined function, it is executed. If the command matches a name of an executable (binary) file, the shell (the parent) spawns a new (child) process which runs the binary program. If the command matches the name of a text file marked executable, the shell assumes that it is a shell procedure. To execute this procedure, the shell spawns a subshell that executes the commands specified in the file.

By default, the shell will search for external commands based on the value of the PATH environment variable. If the command can not be found in any of the directories specified by the path, it searches the current directory. If you specify a path with the command, the shell will not search the path for the specified command. Instead, it only searches the path specified on the command line.

Shell Commands

The Bourne shell is a programmable shell with several forms of structured commands similar to those found in traditional higher-level programming languages. The following commands can be used to program the Bourne shell. The return value, unless otherwise stated, will be the value returned by the last executed simple command.

The for command lets you execute a specified list of commands. The syntax for this command is:

for identifier [in word ...] do list done

where identifier is a variable which is assigned the value(s) specified by word ... and executes the commands specified by list. If the word option is not specified, the shell executes the list of commands for each positional parameter that is set.

The case command can be used to execute commands based on a particular setting of another variable. The syntax for this command is:

case word in pattern [| pattern] ...) list;; [pattern [|pattern]...) list;;] esac

where word is the variable to match with one of the specified patterns. When a matching pattern is found, the commands specified by list are executed. The vertical bar is used to denote an "or" operation.

You can also use an if construct to specify conditions in the script. The syntax for this command is:

if List then list [elif List] ... [else list] fi

where the commands specified by list are executed if the last command executed by List has a return value of zero. The elif construct represents an else if phrase and the corresponding list commands are executed if the previous List returns a non zero value and the last command executed by the List following the elif phrase returns a value of zero. The else clause is executed only if all other conditions are return non-zero values.

The while clause can be used to execute a list of commands while a certain condition holds true. The syntax for the while command is:

while List do list done

where the commands specified by list are executed after the last command specified by the List variable returns a zero value. The shell will continue to execute the commands until the last command specified in List returns a non-zero value.

The until command works like the while command except the return values are reversed. This means the commands in list are executed as long as the last command specified by List returns a non-zero value. This repeats until the last command in List returns a zero value.

Commands executed within parentheses are run within a subshell. To execute commands within the current shell, enclose them in braces ('{' and '}').

Function Definition

You can define a function for use with other shell commands. To do this, specify the name of the function followed by a set of parenthesis. The commands that are associated with the name should follow, and be enclosed within braces and separated by semi-colons. The syntax for this is:

name () {list;}

where name is the name of the function and list is a set of commands that are executed when the function is invoked. For example, the following command defines a function L which displays the list of files in the current directory piped through the page formatter:

L( ) {/bin/ls -l | pg}

Special Commands

The following table shows a listing of the special commands to the Bourne shell. These commands are built into the Bourne shell and are executed in the shell process. Next to each command will be a brief description of the command.
Command             Description
------------------------------------------------------------------------------
:                   The null command returns a zero exit value
. file              Executes commands specified in file using the search path and not starting a subshell
break [n]           Exits the nth iteration from the for, while, or until loop
continue [n]        Resumes the nth iteration of the for, while, or until loop
cd [directory]      Changes to the specified directory, or to $HOME if none specified
echo [string]       Writes string to standard output
eval [list]         Executes the commands specified in list
exec [list]         Executes the commands in list in place of the current shell
exit [n]            Causes the shell to exit with a return code of n
export [name]       Marks the specified name for export to the environment of subsequent commands.
hash [-r][command]  Finds and remembers the path of each specified command or if -r is used, forget location
pwd                 Displays the current working directory
read [name ...]     Reads one line from standard input and assigns to name
readonly [name...]  Marks name to be read-only
return [n]          Causes a function to return a value of n
set [flag[argument] See the section on Setting Flags
shift [n]           Shifts the command line arguments to the left n places ($0 is never shifted)
test Expression     Evaluates the expression
times               Displays the accumulated user and system times for processes running from the shell
trap [command][n]   Runs command when the shell receives a signal n
type [name...]      For each name specified, indicates how the shell would interpret it as a command
ulimit [flag[var]]  Sets or queries process size limits using a specified flag
umask [nnn]         Sets the access mode mask to be used with newly created files.
unset [name...]     Removes the specified variable, name from the environment
wait [n]            Waits for the child process whose process number is n or all if none specified

Setting Flags

You can control the action of some shell commands as well as AIX commands by the use of environment variables. Once a variable is set, it's value is passed from the current process to any child processes it creates. A child's ability to change the value of a variable will not affect the value of the variable as seen by the parent. In other words, the child process can not change the values of its parent's variables. The format for the set command is:

set [flag [argument] ...]

where flag can be one of the values to be set from the table below and arguments are assigned in order to the symbols $1, $2, $3, etc. If the flag is preceded with a dash, the variable is set. You can precede the flag with a plus sign if you wish to unset a variable.

Flag  Brief Description
-------------------------------------------------------------------------------
a     Marks for export all variables for which an assignment is performed
C     Prevents the shell from overwriting existing files when redirection is used
e     Exits immediately if a command returns a non-zero value and is run outside a loop
f     Disables filename substitution
h     locates and remembers the commands called within functions as they are defined
k     places all the keyword parameters in the environment
n     Reads commands, but does not execute any of them (syntax checking scripts)
t     exists after executing one command
u     Treats an unset variable as an error and exits immediately
v     Displays the shell input lines as they are read
x     Displays all the commands and their arguments before they are executed
-     Does not change any of the flags

Command Substitution

You can take the output of one command and use it as an argument to another command within the Bourne shell. To do this, place the command to be used as an argument within grave accents ( ` ). This will tell the shell to do a command substitution of that command for an argument in another command. The shell will then replace the command within the grave accents with the output of the command. This is particularly useful for assignments such as today = `date`. You can nest commands by placing a backslash before the nested grave accents.

If you prefer to get input from the keyboard instead of another command, you can use the read command. The read command will read a value from the keyboard and assign each word to the specified arguments. If more words are specified than arguments, the extra words are assigned to the last argument of the read command.

File Name Substitution

The Bourne shell provides a sophisticated pattern matching and file name substitution ability. To match any string, including the null string, use the asterisk (*). The question mark (?) can be used to match a single character. Characters enclosed within square brackets can signify a set of characters to match. Placing an exclamation point after the open bracket will signify a pattern that matches none of the characters specified with the brackets. A hyphen between letters that are located in brackets signifies a pattern to match all characters included in the specified range. For example the pattern .[A-Z]* matches all files whose first two characters are a period and a capital letter.

There is an exception to the filename substitution rules. Any file that begins with a period will not match a pattern. In other words, to see a list of all files that begin with a period, you would have to use the pattern .* . If the pattern does not match any file names, the pattern is returned. Infinite recursion can occur if files have names that include any of the special pattern characters.

Redirecting Input and Output

Many AIX commands take input from stdin, send output to stdout, and send errors to stderr. The Bourne shell allows you to redirect standard input, standard output, or standard error to another file or command. These devices are given file descriptors zero through two respectively. File descriptors three through nine are free to use by your applications and can also be redirected as needed. File name substitution or pattern matching does not take place after a redirection symbol. Therefore, care should be taken to ensure files are not created using any of the special pattern characters.

Redirection symbols should be used after the command and any of its arguments. The redirection symbol should then be followed by the file or command for which the redirection is occurring. The < symbol is used to redirect standard input from the specified file. The > sign redirects standard output to the specified file. The > > symbol appends the output of the command to file specified, creating it if it does not exist. You can redirect a specific file descriptor by placing its number directly before the redirection symbol. For example, cc prog1 2> > errror.file will append all errors produced by the C compiler to the file error.file. You can redirect more than one file descriptor by placing each one with its own redirection symbol.

Environment Variables

When you run a command, the shell automatically assigns the command to $0. The first argument is assigned to $1 and so on for each argument on the command line up to $9. To access any arguments past position nine, you will need to use the shift command. In addition to passing arguments, the shell passes a copy of the environment. The environment is a list of parameter values that can be used by the child process.

The Bourne shell lets you create and assign values to system environment variables as well as user defined variables. A variable name is a sequence of letters and numbers and can include underscores. The only restriction is that it not begin with a number. A value can be assigned to a variable by typing the variable name followed by an equals sign and then the value to be assigned. Do not place any spaces around the equals sign, or they will be included as part of the variable name or value. If you wish to use spaces in the value, place the entire value within quotation marks (" "). If double quotation marks are used, the shell will still perform variable name substitution. In other words, values are substituted for their variables. Once a value has been assigned to a variable, it can be used by placing a $ before the variable name. If the value is to be used within a string, you can include the variable name (but not the $) within braces. The braces will separate the variable name from the rest of the string. For example, to show the value of the environment variable HOME, use the command

echo $HOME

Environment variables can be exported to subsequent subshells by using the export command.

Below is a table showing the system environment variables and a brief description about them.

Variable     Brief Description
------------------------------------------------------------------------------
CDPATH       The search path for the cd command
HOME         The subdirectory that becomes current upon login and as a default for cd
LANG         Determines the locale to use when LC_ALL does not specify one
LC_ALL       Determines the locale to be used to override any previously set values
LC_COLLATE   Defines the collating sequence to use when sorting
LC_CTYPE     Determines the locale for the interpretation of sequence of bytes
LC_MESSAGES  Determines the language in which messages should be written
LIBPATH      The search path for shared libraries
LOGNAME      Your login name, marked read-only by the /etc/profile script
MAIL         The path name of the file used by the mail system to detect the arrival of new mail
MAILCHECK    The number of seconds that the shell lets elapse before checking for new mail
MAILPATH     A list of programs separated by colons where the shell will notify you of new mail
MAILMSG      The mail notification message
PATH         The search path for commands separated by colons
PS1          The string to be used as the primary system prompt
PS2          The value of the secondary prompt (when the shell finds a new-line character)
IFS          Characters that are to be used as internal field separators
SHACCT       The shell writes an accounting record in the file for each shell script executed.
SHELL        The path name of the shell (should be exported by the $HOME/.profile script
TIMEOUT      The number of minutes the shell remains inactive before it exits.

The Restricted Shell

The restricted shell works the same as the Bourne shell, except the user is not allowed to change directories, set the value of the path or shell environment variables, specify a path or command containing the '/' character, or redirect output. These restrictions are useful for controlling the actions of a a certain account.

HELPFUL HINTS

You can determine the number of arguments passed to a shell by using the $# environment variable.

The value of the last command to be executed will store its return code in the $? variable.

You can see the value of user variables by using the set command. The env command can be used to display the values of the system variables.

REFERENCES/MANUALS

InfoExplorer provides online help regarding the Bourne shell

Appendix B of the AIX Version 3.2 System User's Guide is devoted to the Bourne shell.

Many books exist in the library and your local bookstore that cover AIX (UNIX) and the Bourne shell. Search through these for one that explains the amount of information you need at a level corresponding to your expertise with AIX.

(c) Copyright UCF Computer Services I& R Support 07/27/93