Shell Variables

  1. Unix Shell Scripting
  2. Shell Basics
  3. Testing in bash
  4. Capturing User Input
  5. Scripting : Exercise 1
  6. Debugging
  7. Bourne/Bash/Korn Commands
  8. Shell Variables
  9. IO Redirection
  10. Pipes
  11. Operators, Wildcards and Expressions
  12. Flow Control
  13. Scripting : Exercise 2
  14. Shell Differences
  15. String Functions
  16. awk
  17. xargs
  18. Power Tools
  19. Exercise 3

In Unix there are three kinds of variables: System Variables (you normally can’t change these), Environment Variables (which are yours, and specific to your environment) and Shell Variables (which you declare and use in programming).

Bourne, bash and Korn allow you to have variables, just like any programming environment. In Bourne/bash/Korn, though, variables do not need to be declared. To create and assign a value to a variable, command:

myvar=value

To use the value of the variable later, use

$myvar

or

${myvar}

The latter syntax is useful if the variable name is immediately followed by other text.

Showing All Variables

Display your variables with this series of commands:

set shows all variables (local and exported)
env shows only environment- and user-exported (whole-environment) variables (not local)
export shows exported variables
unset removes a variable
declare also shows all env vars

Setting Variables

You can create or set variables to new values simply by assigning a value:

HOME=/home/g/glenn

To get the value back from the variable, place a $ before it:

echo $HOME

Which returns:

 /home/g/glenn 

Note that

echo HOME

will get you:

HOME

If there is a space in the variable’s value, use double quotes to preserve them (and to allow them in the first place):

fullname="John Doe"

Often in scripts or commands, you’ll need to use environment variables in text without spaces. This can confuse the shell.

Try these lines:

mycolor=blue; export mycolor
echo “My dog is $mycolorish.”

Now try:

echo “My dog is ${mycolor}ish.”

Remember the uses of the escape character \ .

myval=50 #(you just assigned a variable)

Now display $50 (fifty dollars):

echo \$$myval

If you refer to a variable that hasn’t been defined, the shell substitutes the empty string. Try this:

echo aaa $FOO bbb
echo xxx ${FOO}yyy

What do you get?

Environment Variables

At the command line, type:

declare

to see the environment variables available to you. Notice particularly the MAIL, PATH, HOME and LOGNAME variables, which can be useful in scripting.

To add permanent environment variables, edit the .bashrc or .profile file in your home directory:

vi .bashrc

and add your variable name and value:

userlog=/var/users.log
export userlog

Exporting Variables

Declaring and populating a variable makes its value available to the current shell process, but other shell processes you might be running would not be able to access them. To make a variable available system-wide, you need to export it:

MYVAR=/var/user.log; export MYVAR
#this will work in Bourne/bash/Korn

MYVAR=/var/user.log
export MYVAR
#this will work in Bourne/bash/Korn

export MYVAR=/var/user.log
#this will only work in bash

Declare and export a variable.

Use echo to see if the variable’s value is available in your current shell.

Now open another shell and test with echo again. Did your variable export?

“Automatic” Variable Export to Subshells

Another of many differences between Bourne and bash is that bash supports automatic variable export to subshells:

Variables present in the shell’s initial environment are automatically exported to child processes. The Bourne shell does not normally do this unless the variables are explicitly marked using the export command.
http://www.math.utah.edu/docs/info/features_1.html

Create and populate a new variable. Do NOT export it.

Now open a new subshell using the bash, sh or ksh command.

Use echo to see if the variable’s value is available.

Using Quotes to Enclose Variables

Sometimes you’ll need to protect variables in double quotes. This is usually important when your variable’s value either (a) contains spaces or (b) is the empty string. Consider this:

#!/bin/bash
X=""
if [ -n $X ]; then
# -n tests to see if the argument is non empty
echo "the variable X is not the empty string"
fi

This script will return:

the variable X is not the empty string

Why? Because the shell expands $X to the empty string. The expression [ -n ] returns true because it is no longer provided with an argument! See Order of Operations for an explanation; the short one is that the shell “got to” the variable first. Put your variables in quotes to ensure you get what you expect:

#!/bin/bash
X=""
if [ -n "$X" ]; then # -n tests to see if the argument is non empty
echo "the variable X is not the empty string"
fi

In this example, the expression expands to [ -n “” ] which returns false, since the string enclosed in quotes clearly is empty.

Dealing With Spaces in Variable Output

Note that if the value of a variable will return with embedded spaces, you need to protect it with quotes. Try this example now:

#!/bin/bash
color1="red chile"
color2="green chile"
color3="christmas"
for x in $color1 $color2 $color3
do
echo $x
done
  1. Run this script.
  2. What did you get?
  3. How can you fix this?

Here’s the point: variables should be protected with quotes unless you are sure that their value does not contain any spaces.

Variable Substitution (quasi-variable constructs)

Sometimes in scripting you won’t know if a variable has been set, or if it’s non-null. You can perform variable substitution so that you can handle this contingency in code.

${VAR:-expression} #assume expression equals "3"
Use default value: if VAR is set and non-null, expands to $VAR. Otherwise, expands to expression.

${VAR:=expression}
Set default value: if VAR is set and non-null, expands to $VAR. Otherwise, sets VAR to expression and expands to expression.

${VAR:?[expression]}
If VAR is set and non-null, expands to $VAR. Otherwise, prints expression to standard error and exits with a non-zero exit status.

${VAR:+expression}
If VAR is set and non-null, expands to the empty string. Otherwise, expands to expression.

${#VAR}
Expands to the length of $VAR.

The above patterns test whether VAR is set and non-null. Without the colon, they only test whether VAR is set.