Chapter 5. Variables

The results of commands can be written to a file or saved in variables. Because variables are saved in memory, they tend to be faster to examine than files. Bash doesn't put an upper limit on the size of a variable: They are large enough to contain anything you will ever need to hold.

Using variables is essential to shell script programming. This chapter is an in-depth look at variables and how they are used in the shell, from basic variables to expanding variables with the eval command.

Variable Basics

Variables are declared using the Bash declare command. To declare a variable named COST, use this:

$ declare COST

Use the built-in typeset statement for compatibility with the Korn shell. If you are using Bash, use declare instead. declare has all the features of the older typeset command.

Choosing good variable names is important. One time, when I was grading a first-year computer science assignment, a student used 26 variables named A to Z. There was no explanation about what the variables represented and it took me half an hour to determine whether the program actually worked. (Surprisingly, it did.)

Names should also be consistent. In the mutual fund industry, for example, “portfolios,” “accounts,” and “funds” often mean the same thing. It is better to use one of these three names throughout your script. If three different terms are used, the reader might assume there are subtle differences in meaning between them.

Because Bash does minimum checking of variable names, even with the nounset option turned on, another common mistake is using a variable that looks the same. In my first year in university, I ran into an old friend who was frustrated because his Fortran program wasn't working. When I examined it closely, I saw that he had declared a variable called HIGH, but in the body of his program he spelled the variable HI. When the program printed the value of HIGH, it was zero because it was never actually assigned a value. The same kind of situation can occur in Bash scripts.

Variable names begin with a leading alphabetic or underscore character followed by additional alphanumeric characters or underscores.

Although variables can be in upper- or lowercase, tradition dictates variables are named in uppercase so as not to be confused with shell commands, which are almost always in lowercase. TOTAL, ORDERS_EUROPE, and _W3C are all legitimate variable names. There are no reserved words, which are words that are reserved for a specific purpose in the shell.

Variables are assigned new values with an equals sign (=). To assign an empty string to a variable, don't supply any value.

$ COST=

Otherwise, include some text to be assigned.

$ COST=0

Although printf %d prints a zero for both a value of zero and an empty string, Bash considers the two values to be different. A variable with no value is not the same as a variable with a value of zero.

Values can also be assigned with the let statement described in Chapter 6.

Bash differentiates between a variable's name and the value the variable represents. To refer to the value of a variable, you must precede the name with a dollar sign ($).

$ printf "%s" $COST
0

The dollar sign means “substitute.” The shell replaces $COST with the value COST represents. In this case, the value of COST is zero. After substituting the value of COST, the command becomes:

$ printf "%d" 0

Bash executes this command and displays a zero.

Values can be assigned an initial value when the variable is first declared.

$ declare COST=5
$ printf "%d" $COST
5

Because declare is a command, variables are created only when the declare command is executed. They remain in existence until the script ends or until the variable is destroyed with the built-in unset command.

$ unset COST

The unset command is a command-line convenience. In well-structured scripts, variables are declared at the start of a script and are not unset. This prevents confusion because the programmer can be sure that the variables always exist while the script is running.

The results of a command can also be assigned to a variable. If a command is contained in backquotes ('), everything written to standard output is stored in the variable being assigned instead.

$ declare NUMBER_OF_FILES
$ NUMBER_OF_FILES='ls -1 | wc -l'
$ printf "%d" "$NUMBER_OF_FILES"
14

Predefined Variables

Bash has more than 50 predefined variables. These variables, created when Bash is first started, provide information about the Bash session and can be used to control some of the shell's features.

Some of these variables have special properties that might be lost if you unset the variable and then create a new one with the same name. For example, the variable RANDOM contains a random number. If you delete RANDOM with unset and declare a new variable called RANDOM, this new variable is a normal shell variable and does not contain random numbers. Therefore, it's best to avoid creating variables with the same name as the predefined variables.

The declare command, with no switches, lists all currently defined values.

  • BASH—. The full pathname of Bash.

  • BASH_ENV—. In a shell script, the name of the profile file executed before the script was started.

  • BASH_VERSION—. The version of Bash (for example, 2.04.0(1)-release).

  • COLUMNS—. The number of characters per line on your display (for example, 80).

  • FUNCNAME—. If inside a function, the name of the function.

  • HOSTNAME—. The name of the computer. Under some versions of Linux, this can be the machine name. On others, it can be a fully qualified domain name.

  • HOSTTYPE—. Type of computer.

  • HOME—. The name of your home directory.

  • IFS—. The internal field separator, a list of characters used to split a line into shell words.

  • LINENO—. The current line number in a script or function.

  • LINES—. The number of horizontal lines in your display (for example, 24).

  • OSTYPE—. The name of the operating system.

  • PATH—. Colon-separated list of search paths to find a command to execute.

  • PPID—. The process ID of the shell's parent process.

  • PROMPT_COMMAND—. Command to execute before the setting of the PS1 primary prompt string.

  • PS1—. The primary prompt string.

  • PS2—. The secondary prompt string.

  • PS3—. The select command prompt string.

  • PS4—. The trace command output prefix string.

  • PWD—. The current working directory (as set by the cd command).

  • RANDOM—. Returns a random number between 0 and 32767 each time it is referenced.

  • SHELL—. The preferred shell to use; for programs that start a shell for you.

  • TERM—. The terminal emulation type (for example, console).

Linux distributions define additional variables. The presence of these variables depends on your particular distribution. Many are declared for the use of applications.

  • DISPLAY is the X Window display server.

  • EDITOR is your default editor. Historically, this was used to indicate a line editor to use when a visual editor was not available (see VISUAL).

  • ORGANIZATION is the name of your organization (usually the contents of /etc/organization).

  • TERM is the terminal emulation (for example, xterm for an xterm session, or linux for the Linux console).

  • VISUAL is your default editor, usually the same as EDITOR.

  • WINDOWMANAGER is the path to your current X Windows window manager.

A complete list appears in the reference section at the end of this chapter.

The Effect of Quotations

Those people familiar with other computer languages might be confused by the way Bash uses quotation marks. Single and double quotes are not used to delineate strings or characters, but to control how the shell groups characters and interprets special characters within a string. Bash calls this process word splitting.

$ COST=0
$ COST="0"

These two assignments produce the same result: COST is assigned a value of 0. The double quotes explicitly show that the value to assign to COST includes the character zero. Short alphanumeric values can be assigned to variables without quotations. However, when the string contains spaces, it's no longer apparent what value is to be assigned. Consider the following example.

$ DISTRIBUTION_CENTERS=London
$ printf "%s" $DISTRIBUTION_CENTERS
London
$ DISTRIBUTION_CENTERS=London ; Paris ; New York
bash: Paris: command not found
bash: New: command not found
$ printf "%s" $DISTRIBUTION_CENTERS
London

When Bash examines the second assignment statement, it sees a value of London terminated by a space. It assigns that value to the variable. It then sees the semicolon, the command separator, and expects a new statement to follow. It tries to execute the Paris command (there is none). It tries to do the same with the New command, giving it the York argument.

For this reason, it is a safe practice to enclose all assignment values in double quotation marks. Even if your company only has a distribution center in London, there's always the chance that a new distribution center will be added to the string, causing the shell script to crash. Always enclosing values in quotes ensures that Bash knows exactly what value is to be assigned.

$ DISTRIBUTION_CENTERS="London ; Paris ; New York"
$ printf "%s" $DISTRIBUTION_CENTERS
London;Paris;NewYork

The results are still not correct. Bash took the DISTRIBUTION_CENTERS value and removed the spaces so that printf doesn't interpret it as separate arguments of London, ;, Paris, ;, New, and York. The printf argument must also be enclosed in double quotes to keep the value of the variable as a single argument with the spacing intact.

$ printf "%s" "$DISTRIBUTION_CENTERS"
London ; Paris ; New York

Again, it is a safe practice to always enclose variable substitutions with quotes.

Because the quotation marks are not delimiters but hints on how to interpret special characters, they can be used back-to-back. This is a convenient way to separate variables from the surrounding text in a string.

$ TAX=7.25
$ TAX_MESSAGE="The tax is ""$TAX""%"
$ printf "%s" "$TAX_MESSAGE"
The tax is 7.25%

Separating each of the quoted pieces with a space would result in the same problem you saw previously: Bash would treat them as three individual values.

Alternatively, a variable substitution's variable name can be enclosed in curly braces to make it clear where the variable's name begins and ends.

$ TAX_MESSAGE="The tax is ${TAX}%"

Besides space interpretation, another effect of quotation marks is that no pattern matching is done. Normally, for example, the asterisk (*) represents all the files in the current directory. Quotation marks prevent the asterisk from being replaced with a list of files.

$ printf "%s
" *
orders.txt
archive
calc.sh
$ printf "%s
" "*"
*

To print strings without interpreting the special characters inside, use single quotes. Double quotes do not prevent Bash from interpreting the special characters $, ', and , but single quotes leave all characters unchanged.

$ printf "%s" '$TAX_MESSAGE'
$TAX_MESSAGE

In this case, the single quotes prevent Bash from interpreting the value as a variable substitution because the dollar sign is not treated specially.

The backslash () acts like single quotes for one character, leaving the character unchanged. For example, to print a double quote mark, do this:

$ printf "%s" """
"

The backslash indicates that the second quote mark is to be treated as a character, not as the ending quote of a pair of quote marks.

The printf formatting code %q (quoting) prints backslashes before every character that has a special meaning to the shell. Use this to ensure that spacing is left intact.

$ printf "%q" "$TAX_MESSAGE"
The tax is 7.25%

For example, reading from files is affected by %q. If the printed variables contain spaces, read treats the spaces as separators unless they are protected with backslashes.

$ printf "%q %q
" "Alpha Systems Inc" "Key West, Florida" > company.txt
$ read COMPANY LOCATION < company.txt
$ printf "%s
" "$COMPANY"
Alpha Systems Inc
$ printf "%s %s
" "Alpha Systems Inc" "Key West, Florida" > company.txt
$ read COMPANY LOCATION < company.txt
$ printf "%s
" "$COMPANY"
Alpha

The read command has no knowledge of what text on the line belonged originally to which variable. It assumes that the values are separated by spaces and assigns Alpha to COMPANY. When %q is used, read knows that the backslash protected spaces belong with the first value and it reads everything up to the first unprotected space, assigning Alpha Systems Inc to COMPANY.

Word splitting is controlled by the value of the special variable IFS. Normally, IFS treats spaces, tabs, and newline characters as word delimiters—that is, it uses whitespace characters. If the content of IFS is changed, the new characters are used as word delimiters. However, this is an older feature for compatibility with the Bourne shell and the IFS variable should not be altered by scripts because newer features such as %q formatting are available.

Whenever values are assigned or are substituted with a dollar sign, it is good practice to always enclose the values in double quotes to prevent problems with values containing spaces.

Variable Attributes

All Bash variables are stored as simple strings. Each variable has certain options called attributes, which can be turned on or off by using the declare command in a similar way to shell options and the shopt command.

If a variable is declared with the -i (integer) switch, Bash turns on the integer attribute for that variable. The shell will remember that the string should be treated as an integer value. If a non-numeric value is assigned to an integer variable, Bash does not report an error but instead assigns a value of zero.

$ declare -i NUMBER_ACCOUNTS=15
$ printf "%d
" "$NUMBER_ACCOUNTS"
15
$ NUMBER_ACCOUNTS="Smith" # mistake
$ printf "%d
" "$NUMBER_ACCOUNTS"
0
$ NUMBER_ACCOUNTS=12
$ printf "%d
" "$NUMBER_ACCOUNTS"
12

Sometimes an attempt to assign a string produces an error, but you can't rely on this behavior.

$ NUMBER_ACCOUNTS="Smith Account" # mistake
bash: Smith Account: syntax error in expression (error token is "Account")

The attributes of a variable can be displayed with the -p (print) switch.

$ declare -p NUMBER_ACCOUNTS
declare -i NUMBER_ACCOUNTS="12"

The information is displayed in such a way that it can be saved for use in another script. This allows you to experiment with declarations at the command prompt and then write the declarations to a script file when you are satisfied with the results.

The integer attribute can be turned off with a plus sign.

$ declare +i NUMBER_ACCOUNTS # turn off integer attribute
$ printf "%d
" "$NUMBER_ACCOUNTS"
bash: printf: Smith Account: invalid number
$ printf "%s
" "$NUMBER_ACCOUNTS"
Smith Account

Although Bash does not consider the assignment of a non-numeric value an error, the printf command does report that the value can't be formatted as a number.

Like the printf command, integer variables can be assigned octal or hexadecimal numbers as well.

$ declare -i NUMBER_ACCOUNTS=0X0F
$ printf "%i
" "$NUMBER_ACCOUNTS"
15

Constants are unchanging variables that are created with the -r (read-only) attribute. If you attempt to assign a value to a constant, Bash reports an error. Suppose the constant COMPANY has the name of a company.

$ declare -r COMPANY="Smith and Jones"
$ printf "%s
" "$COMPANY"
Smith and Jones
$ COMPANY="Wilson Distribution"
bash: COMPANY: readonly variable

The readonly attribute can be turned off using a plus sign. However, this can make your scripts confusing to read because the reader will assume that a readonly variable is always read-only. Either remove the readonly attribute or change the structure of the script.

Arrays

Arrays are lists of values that are created with the -a (array) attribute. A number called an index refers to the position item in the array. Bash arrays differ from arrays in other computer languages because they are open-ended. Arrays can be any length and are initially filled with empty strings for items.

$ declare -a PRODUCTS

New items are assigned to the array using square brackets to indicate the position in the list. The first position is position zero (not one). If an initial value is specified, it is assigned to the first position. Assigning one value is not particularly useful but is included for compatibility with other shells. Alternatively, the initial values can be assigned to specific positions by including a position in square brackets.

$ declare -a DEPT[0]="accounting" DEPT [1]="shipping" 
DEPT [2]="customer service"

Because of the square brackets, use curly braces to delineate the variable name and supercede the shell's pathname matching process.

$ echo "${ DEPT [0]}"
accounting
$ echo "${ DEPT [2]}"
customer service

All unassigned positions in an array have no value. The position number 5 in the PRODUCTS array, for example, is initially an empty string. It can be assigned a value of hammers with an assignment statement.

$ printf "%s" "${PRODUCTS[5]}"

$ PRODUCTS[5]="hammers"
$ printf "%s" "${PRODUCTS[5]}"
hammers

If there is an item in position zero, it is also the value returned when no position is specified.

$ PRODUCTS[0]="screwdrivers"
$ printf "%s" "$PRODUCTS"
screwdrivers
$ printf "%s" "${PRODUCTS[0]}"
screwdrivers

The entire array can be accessed using an asterisk (*) or an at sign (@) for the array position. These two symbols differ only when double quotes are used: The asterisk returns one string, with each item separated with the first character of the IFS variable (usually space), and the at sign returns each item as a separate string with no separation character.

$ printf "%s" "${PRODUCTS[*]}"
screwdrivers hammers
/home/kburtch [bash]
$ printf "%s" "${PRODUCTS[@]}"
screwdrivershammers

In this example, the at sign version requires two separate %s formatting codes to display the array properly, one for each array item.

$ printf "%s %s
" "${PRODUCTS[@]}"
screwdrivers hammers

Multiple values can be assigned with a list in parentheses.

$ DIVISIONS=("North America" "Europe" "Far East")
$ printf "%s
" "${DIVISIONS[*]}"
North America Europe Far East

The list items can have an optional subscript.

$ DIVISIONS=([3]="North America" [2]="Europe" [1]="Far East")
$ printf "%s
" "${DIVISIONS[*]}"
Far East Europe North America

Combining a list with a declare command, arrays can be assigned values at the time they are created.

The number of items in the array is returned when # is used in front of the variable name with a position of * or @. The items need not be assigned consecutively and the number doesn't reflect where the items are stored.

$ printf "%d" "${#PRODUCTS[*]}"
2

Individual array values can be removed with the unset command. Erasing a value by assigning the array position an empty string doesn't destroy it: The empty string is still treated as an array item whenever the items are counted.

The read command can read a list into an array using an -a (array) switch. When this switch is used, each item on the line of input is read into a separate array position.

The array attribute is the only variable attribute that cannot be turned off after it is turned on. If Bash allowed the attribute to be turned off, the data in the array would be lost when the array became a normal variable.

Exporting Variables and the Linux Environment

Shell variables exist in the script or interactive sessions only where they were declared. In order to make shell variables available outside of their place of origin, they have to be declared as exportable. Variables are marked as exportable with the export attribute using the declare -x (export) switch. The export attribute reminds the shell that you want to “export,” or provide the variable, to all programs run by the script.

For example, the program CVS requires a variable called CVSROOT to exist for all its programs.

$ declare -x CVSROOT="/home/cvs/cvsroot"

In the same way, any variables declared in your profile scripts must be exported or they won't exist at the command prompt. They will disappear after the profile scripts are finished running.

When a variable is exported, any changes made by programs executed by the script are discarded when the program completes. If a second script were to change CVSROOT to the value /home/local/cvsroot, when the second script is finished, CVSROOT will once again be /home/cvs/cvsroot. The changes are “rolled back.”

Create global constants by using both the export and read-only switches.

$ declare -rx COMPANY_BRANCH="West Coast Branch"

COMPANY_BRANCH is only a read-only variable in the current script. When it's exported to a second script, it's exported as a normal variable—the read-only effect is lost. The reason for this strange behavior is rooted in the way Linux shares environment variables between programs and has nothing to do with the Bash shell itself.

Environment variables are the variables Linux shares between a program and the program that executed it. Like layers of an onion, each program must explicitly export a variable into the environment for the next program to see it.

Although Linux has provisions for exporting environment variables, there is no way to assign any attributes to them. Linux has no notion of attributes. Bash attributes were thought up after environment variables were first invented. When Bash variables are given to Linux to share with a new program, the attributes are lost. When the second shell script starts, it has no way of knowing what the original attributes were.

The variables shared with a new program are copies of the original. If a script declares an exported variable and runs a second script, any changes made to the variable by the second script are invisible to the first. There is no way for a second script to assign a new value to a variable that the first script will see. Unlike other programming languages, exporting shell variables is a one-way street.

Suppose there are two scripts called outer.sh and inner.sh. outer.sh declares a variable and then runs the inner.sh script, as shown in Listings 5.1 and 5.2.

Example 5.1. outer.sh

# outer.sh
#
# This script runs first.

declare -rx COMPANY_BRANCH="West Coast Branch"
bash inner.sh
printf "%s
" "$COMPANY_BRANCH"

exit 0

Example 5.2. inner.sh

# inner.sh
#
# This script is run by outer.sh.

printf "This is the inner script.
"

declare -p COMPANY_BRANCH
COMPANY_BRANCH="East Coast Branch"
printf "%s
" "$COMPANY_BRANCH"

printf "Inner script finished
"

exit 0

When outer.sh is run, the COMPANY_BRANCH variable is read-only. However, inside inner.sh, the read-only attribute has been lost. inner.sh changes the variable to a new value, but when inner.sh is finished, outer.sh shows that the variable's value is unchanged.

$ bash outer.sh
This is the inner script.
declare -x COMPANY_BRANCH="West Coast Branch"
East Coast Branch
Inner script finished
West Coast Branch

The only way to return a value to the calling program is to write it to a file (or standard output) and have the calling program read (or assign) the value back into a variable.

The eval Command

Bash performs variable substitutions as variables are encountered in a command. Before a command is executed, Bash searches the command for all dollar signs and inserts the value of variables before the command is carried out. Bash performs this substitution once. If a variable contains a value with a dollar sign in it and the value is substituted into a command, the value with the dollar sign remains unchanged.

$ declare —rx COMPANY="Value Book Resellers"
$ declare —rx TITLE='$COMPANY'
$ printf "%s
" "$TITLE"
$COMPANY

Before the printf is performed, Bash substitutes the value "$COMPANY" for TITLE. Bash does not repeat the substitution process to replace the COMPANY variable with "Value Book Resellers". Substitutions are performed only once.

Under rare cases, you might want to force Bash to perform an additional round of substitutions. The Bash eval command can do substitutions on demand and run the results. Take the following simple example, shown in Listing 5.3, whereby one of three variables is shown on the screen.

Example 5.3. eval_example.sh

# eval_example.sh

shopt -s -o nounset

declare -r DISPLAY_VARIABLE='$SALES_EAST'

declare -i SALES_EAST=1000
declare -i SALES_WEST=2000
declare -i SALES_NORTH=3000


printf "DISPLAY_VARIABLE = %s
" "$DISPLAY_VARIABLE"
printf "reprocessed with eval, DISPLAY_VARIABLE = %s
" 
'eval printf "%s
" "$DISPLAY_VARIABLE"

This script can display the sales figures for one of three company branches. The constant DISPLAY_VARIABLE contains the variable to display, SALES_EAST, SALES_WEST, or SALES_NORTH. But if DISPLAY_VARIABLE is substituted, only the string "$SALES_EAST" is printed.

The backquotes run eval and perform a new set of substitutions. The results can be substituted into the original printf command. Now the results are as you expected.

$ bash eval_example.sh
DISPLAY_VARIABLE = $SALES_EAST
reprocessed with eval, DISPLAY_VARIABLE = 1000

In this example, Bash first processes the printf command as

printf "reprocessed with eval, DISPLAY_VARIABLE = %s
" 
'eval printf "%s
" $SALES_EAST'

This only prints $ SALES_EAST because Bash is finished substituting the values of variables. When Bash executes the eval command, there is a second examination of the echo command.

printf "reprocessed with eval, DISPLAY_VARIABLE = %s
" ' printf "%s
" 1000'

Because Bash also attempts to run the result, the echo command, a simpler version of printf, is required. eval tries to execute the re-evaluated $DISPLAY_VARIABLE as if it were a command. That is, with eval 1000, Bash would try to execute the number 1000, which is not what you want.

printf "reprocessed with eval, DISPLAY_VARIABLE = %s
" 1000

Although not particularly realistic in this example, the eval command is useful when the user types commands to execute, or when reading commands to execute from a file. The commands can contain variables, dollar functions, and so forth, provided you use eval to process them.

A common pitfall is not following through the substitution process. Suppose, for example, that instead of assigning DISPLAY_VARIABLE the value $SALES_EAST, SALES_EAST was assigned and a second dollar sign was added to the printf statement.

printf "reprocessed with eval, DISPLAY_VARIABLE = %s
" 
'eval printf "%s
" "$$DISPLAY_VARIABLE"

You would get a response similar to this:

reprocessed with eval, DISPLAY_VARIABLE = 14235SALES_EAST

In this case, the first substitution leaves the command:

  printf "reprocessed with eval, DISPLAY_VARIABLE = %s
" 
'eval printf "%s
" $$SALES_EAST'

But $$ is a built-in shell function. Bash doesn't understand that $SALES_EAST is supposed to be nested inside the first dollar sign: it simply reads from left to right, substituting as it does. The second substitution would execute the $$ function, not substitute the value of the SUM variable. To execute this properly, you have to escape the first dollar sign with a backslash to keep Bash from substituting it.

  printf "reprocessed with eval, DISPLAY_VARIABLE = %s
" 
'eval printf "%s
" "\$$DISPLAY_VARIABLE"'

After the first substitution, you get this:

  printf "reprocessed with eval, DISPLAY_VARIABLE = %s
" 
'eval printf "%s
" $$SUM'

This prevents $$ from being treated as a built-in function: Bash substitutes for $SALES_EAST instead. You bypassed these issues in the first example when the dollar sign was inside DISPLAY_VARIABLE.

The same effect can be achieved by escaping some quotation marks in the right places.

Variables and constants form the building blocks of all scripts, but they only serve as storage containers without expressions. These are covered in the next chapter (Chapter 6, “Expressions”).

story.bash: A Story Generator

Listing 5.4 is a complete example showing some of the concepts in this chapter. story.bash is a script that creates a story by substituting words chosen by the user.

Example 5.4. story.bash

#!/bin/bash
#
# story.bash: a story generator
#
# Ken O. Burtch
# CVS: $Header$

shopt -s -o nounset

declare NAME          # a name
declare COLOR        # a color
declare DAY           # a day
declare RELATIONSHIP  # a person's relationship
declare OBJECT        # an everyday object
declare -a ACTIVITY   # a list of everyday activities

# Instructions

printf "%s
" "This is a story generator.  I will ask you for some"
printf "%s
" "common words.  Then I will compose a story."
printf "
"

# Read the variables

read -p "Enter a man's name                       : " NAME
read -p "Enter a color (eg. red)                 : " COLOR
read -p "Enter a day (eg. Monday)                 : " DAY
read -p "Enter a person's relationship (eg. uncle): " RELATIONSHIP
read -p "Enter an everyday object (eg. pencil)    : " OBJECT
read -p "Enter an everyday activity (eg. sleeping): " ACTIVITY[0]
read -p "Enter an everyday activity (eg. reading) : " ACTIVITY[1]
printf "
"
read -p "Press return/enter to read your story"
printf "
"

# Write the story

printf "%s
" "$DAY at work, $NAME realized that he had forgotten to pack"
printf "%s
" "a lunch.  Ignoring his $SHELL prompt, $NAME decided to head"
printf "%s
" "out early and grab lunch from a street vendor."
printf "%s
" "As he got outside of the front door of the office,"
printf "%s
" "$NAME ran into his $RELATIONSHIP carrying a"
printf "%s
" "$COLOR $OBJECT.  His $RELATIONSHIP remarked that it had"
printf "%s
" "been $RANDOM days since $NAME had called.  $NAME"
printf "%s
" "thought he would have been off surfing the net on his"
printf "%s
" "$OSTYPE computer than running into his $RELATIONSHIP.  He"
printf "%s
" "offered to take the $OBJECT to get polished." 
"  He went ${ACTIVITY[0]}"
printf "%s
" "down the street, wishing that his $RELATIONSHIP had stayed"
printf "%s
" "home ${ACTIVITY[1]} instead."

exit 0

Reference Section

Declare Command Switches

  • -a—. Declares an array

  • -f—. Displays a function and its definition

  • -F—. Displays the function name

  • -r—. Declares a read-only variable

  • -x—. Declares an exported variable

  • -I—. Declares an integer variable

Bash Predefined Variables

  • auto_resume—. If set, allows command completion for the names of stopped jobs.

  • BASH—. The full pathname of the shell.

  • BASH_ENV—. In a shell script, displays the name of the profile file executed before the script was started.

  • BASH_VERSION—. The version of Bash (for example, 2.04.0(1)-release).

  • BASH_VERSINFO—. An array holding more detailed version information than BASH_VERSION.

    BASH_VERSINFO[0]

    The major version number (the release).

    BASH_VERSINFO[1]

    The minor version number (the version).

    BASH_VERSINFO[2]

    The patch level.

    BASH_VERSINFO[3]

    The build version.

    BASH_VERSINFO[4]

    The release status (for example, beta1).

    BASH_VERSINFO[5]

    The value of MACHTYPE.

  • CDPATH—. Colon-separated list of directories to search when using the cd command.

  • COLUMNS—. The number of characters per line on your display (for example, 80).

  • COMP_WORDS—. In a programmable completion function, an array of the individual words on the current command line.

  • COMP_CWORD—. In a programmable completion function, the current COMP_WORDS word.

  • COMP_LINE—. In a programmable completion function, the current command line.

  • COMP_POINT—. In a programmable completion function, the current command-line cursor position.

  • COMPREPLY—. In a programmable completion function, the list of completions returned.

  • DIRSTACK—. The list of directories used by dirs, popd, and pushd.

  • EUID—. The effective user ID of the current user.

  • FCEDIT—. The default text editor for the fc command.

  • FIGNORE—. Colon-separated list of prefixes or suffixes to ignore for filename completion.

  • FUNCNAME—. If inside a function, the name of the function.

  • GLOBIGNORE—. Colon-separated pattern list of filenames to be ignored by pathname expansion.

  • GROUPS—. The list of groups of which the user is a member (in numeric format).

  • histchars—. List of characters to be used for the history expansion in commands.

  • HISTCMD—. The position in the command history where the current command is placed.

  • HISTCONTROL—. Determines whether commands preceded by spaces, or repeated commands, are placed in the command history.

  • HISTFILE—. The file containing the command history.

  • HISTFILESIZE—. Maximum size of the HISTFILE command history file.

  • HISTIGNORE—. Colon-separated pattern list of commands to be kept in the command history.

  • HISTSIZE—. The number of commands kept in the command line history (for example, 1000).

  • HOSTNAME—. The name of the computer. Under some versions of Linux, this is the machine name. On others, it is a fully-qualified domain name.

  • HOSTTYPE—. Type of computer.

  • HOME—. The name of your home directory.

  • IGNOREEOF—. If this variable exists, it indicates the number of EOF characters that must be typed before Bash exits.

  • IFS—. The internal field separator, a list of characters used to split a line into sections by the read command.

  • INPUTRC—. The name of the Readline startup file.

  • LANG—. Used to determine the locale category for any category not specifically selected with a variable starting with LC_.

  • LC_ALL—. This variable overrides the value of LANG and any other LC_ variables specifying a locale category.

  • LC_COLLATE—. Controls the sorting order of pathname expansion and pattern matching.

  • LC_CTYPE—. Controls the character classes used by pathname expansion and pattern matching.

  • LC_MESSAGES—. Locale for translation of double-quoted string preceded by a dollar sign.

  • LINENO—. The current line number in a script or function.

  • LINES—. The number of horizontal lines in your display (for example, 24).

  • MACHTYPE—. A description of the computer; a combination of $HOSTTYPE and $OSTYPE.

  • MAIL—. The name of a file to check for incoming mail. It is superceded by MAILPATH.

  • MAILCHECK—. If this variable exists, the number of seconds to check MAILPATH for incoming mail. The default if no value is set is 60 seconds.

  • MAILPATH—. Colon-separated list of files to check for incoming mail.

  • OSTYPE—. The name of the operating system.

  • OLDPWD—. The previous working directory (as set by the cd command).

  • OPTERR—. If set, getopts shows error messages.

  • PATH—. Colon-separated list of search paths to find a command to execute.

  • PIPESTATUS—. An array with a list of exit status values for each command in the last pipe.

  • PPID—. The process ID of the shell's parent process.

  • PROMPT_COMMAND—. Command to execute before the setting of the PS1 primary prompt string.

  • PS1—. The primary prompt string.

  • PS2—. The secondary prompt string.

  • PS3—. The select command prompt string.

  • PS4—. The trace command output prefix string.

  • PWD—. The current working directory (as set by the cd command).

  • RANDOM—. Returns a random number between 0 and 32767 each time it is referenced.

  • OPTARG—. The last argument processed by the getopts command.

  • OPTIND—. The index of the next argument to be processed by the getopts command.

  • SECONDS—. The number of seconds since the Bash was started.

  • SHELL—. The preferred shell to use, for programs that start a shell for you.

  • SHELLOPTS—. Colon-separated list of currently enabled shell options.

  • SHLVL—. Each time a new Bash session is started inside Bash, this variable is incremented.

  • TIMEFORMAT—. The format for the time command.

  • TMOUT—. If greater than zero, indicates the timeout in seconds for an interactive session. Also, the default timeout for the read command.

  • UID—. The ID of the current user (the numeric equivalent of LOGNAME).

Linux distributions define additional variables. The presence of these variables depends on your particular distribution. Many are declared for the use of particular applications.

  • _ETC_PROFILE—. Displays 1 if /etc/profile was executed

  • DISPLAY—. The X Window display server

  • CVSROOT—. The location of the CVS repository

  • EDITOR—. Your default editor. Historically, this was used to indicate a line editor to use when a visual editor was not available (see VISUAL)

  • KDEDIR—. The parent directory for the KDE desktop

  • HOST—. The fully qualified hostname (for example, host.domain.com)

  • INPUTRC—. The location of the inputrc file (for example, /etc/inputrc)

  • LESS—. Contains the default switches for the less command

  • LESSOPEN—. The default command used by less to open a file (for example, |/usr/bin/lesspipe.sh %s)

  • LESSCHARSET—. The console character set to use for less (for example, latin1)

  • LS_COLORS—. The default colors for your ls output on the console, overriding /etc/DIR_COLORS

  • LOGNAME—. The name of the current login

  • ORGANIZATION—. The name of your organization (usually the contents of /etc/organization)

  • PRINTER—. The default printer

  • QTDIR—. The directory containing QT, the widget package for KDE desktop

  • PAGER—. The default paging program, usually less

  • TEMPDIR—. The path of the default temporary directory

  • TERM—. The terminal emulation (for example, xterm for an xterm session, or linux for the Linux console)

  • USER—. Your username for OpenLinux

  • VISUAL—. Your default editor, usually the same as EDITOR

  • WINDOWMANAGER—. The path to your current X Windows window manager

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.3.208