Main Body
4 Shell Variables, Quotes, Command Substitution
Shell Variables
Unix is an operating system but also the name given to its scripting (programming) language. In order to be useful, a computer language needs to be able to store data. Unix supports this capability with shell variables.
There are three kinds of shell variables:
- special
- environment
- program
Special variables
Special variables are unlike what you may have seen in other programming languages. Rather special variables are created and set by the operating system automatically. Consider the following examples:
Positional parameters ($1, $2, …)
Recall that the cat program allows the user to specify inputs as command-line arguments: (In the following examples, the leading dollar sign represents the command prompt; do not type the leading dollar sign.)
$ cat ch1 ch2 ch3
Imagine that you would like to write your own script allowing the user to specify inputs as command-line arguments as in.
$ myscript apple cherry
Example
$ cat arg_demo #!/bin/bash echo The 1st argument is $1 echo The 2nd argument is $2 $ $ ./arg_demo apple cherry The 1st argument is apple The 2nd argument is cherry
number of command line arguments ($#)
The special variable $# holds the number of command-line arguments specified when your script was run.
Examples
$ cat numeg #!/bin/bash echo The number of command line arguments is $# $ $ ./numeg apple cherry The number of command line arguments is 2 $
return code of previous command ($?)
Every Unix command generates a return code typically indicating success or failure. The value of this return code is stored in the special variable $?. Thus each time a Unix command is run the $? variable is updated automatically to hold the return code of the most recently executed Unix command. The use of the return code is important and will become apparent in the chapter on control structures.
Environment variables
Environment variables hold information about the users’s current settings and configuration. By convention, they are typically all UPPERCASE. To display them, type ‘env’
Example
lhiraki@metis:~$ env
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/snap/bin:/usr/courses/bin/x86_64
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
EDITOR=vi
LANGUAGE=en_CA:en
LPDEST=eng206c
lhiraki@metis:~$
Here is an abridged list of environment variables. Some of the typical environment variables include SHELL (current shell), PATH (list of directories the operating system will search in order to find a command), EDITOR (preferred editor), LANGUAGE (preferred display language), LPDEST (preferred printer destination).
Program variables
Program variables are the type of variable that typically come to mind when one thinks of variables in a computer programming language. Program variables are variables which you as the programmer create and set. As Unix is a prototyping language, it is common to dispense with many of the formalities required for variable declarations, etc.
Program variables hold a string, i.e. text, and can be used anywhere text could appear in a program such as a filename, part of the file name, or even a Unix command itself. A variable can hold only one value at a time.
The naming convention for program variables is to use lowercase. Specifically uppercase program variable names should be avoided so as to prevent confusion with environment variables and accidentally overwriting an environment variable.
Eg. 1 An easy way to create and set a program variable is using an assignment statement.
temp_name=/usr/temp cp myfile $temp_name
Assignment statements copy the value to the right of the equal sign to the variable on the left. Important: Assignment statements must not contain spaces, especially around the equal sign.
Eg. 2
month=september echo the current month is $month
When to use $ with variables
When writing to a variable, i.e. setting or changing its contents, do not use the dollar sign. When reading a variable, i.e. accessing its contents, you must use the dollar sign.
Key Takeaway – When to use $ with variables:
Writing to a variable: no dollar sign
Reading from a variable: use dollar sign
Editorial Remark:
One of the key factors affected software maintenance costs is code readability. Most of the time (cost) of maintaining software is spent in having designers read and understand existing code. One way to control and reduce costs (business competitiveness) is to ease readability. By choosing variables which reflect their contents, it makes it easier to understand the code.
Choose self-describing variable names:
Good variable names: | Bad variable names: |
---|---|
|
|
read
The read command collects characters from standard input (STDIN) and stores them in a variable. The read command is typically used in an interactive script to collect user input after an appropriate prompt message. As the read command draws from standard input, and standard input can be redirected from a file, it is possible to prepare inputs (answers) in a file and run the script in a non-interactive fashion.
Example using read command
$ cat readeg echo -n 'What is your name? ' read name echo Hello $name, pleased to meet you! $ $ ./readeg What is your name? Mohammed Hello Mohammed, pleased to meet you! $
What does the option “-n” do in the echo command above?
Hint: type “man echo”. To exit the manual, press “q”.
Key Takeaways
read vs. command line arguments
- Both are ways the user can supply input to a program. Command line arguments are placed on the command line before pressing <ENTER> to run the program. The values are accessed within one’s program using $1, $2, etc.
- The “read” command causes the program to wait for keyboard input (if STDIN has not been redirected from a file). The input is stored in and later accessed from a program variable.
Which method should you use? Refer first to any program requirements. (Does it say, “Prompt the user to enter …” or “specify as a command line argument”?)
Quotes
Single quotes:
Problem:
$ grep Al Shaji employee_list grep: can’t open Shaji
Solution:
$ grep 'Al Shaji' employee_list
Single quotes causes Unix to take everything within the single quotes literally. This is how you would prevent interpretation of characters which would normally have special meaning, for example the space character separating command line arguments.
Double quotes
- Recognize $, \, ` (backtick or backquote)
Exercise 1: Try this out and see the difference double quotes makes
heading=' Name Addr Phone' echo $heading echo "$heading"
Exercise 2: Try this out and see the difference double quotes makes
read operator # enter asterisk * echo $operator echo "$operator"
The double quotes are similar to single quotes in that Unix takes what is within the quotes literally. However, double quotes are “smarter” in that variables and selected meta-characters are interpreted and expanded in spite of the usual literal nature of quotes.
Home directory potential tricky issue (tilde is protected i.e. not expanded within quotes).
Instead of:
datafile="~jasmin/rawdata" cat $datafile # produces "No such file or directory" error
Say (solution 1):
datafile=~jasmin/rawdata cat $datafile
Say (solution 2):
datafile="~jasmin/rawdata" eval cat $datafile
Command substitution
Sometimes a programmer wishes to run a command and use its output at some point within a program. While it is possible to redirect output to a temporary file, load the contents of the file, and then promptly delete it, for small tasks, it is more convenient and efficient to use the technique of command substitution and avoid extra disc access.
Eg. 1 Newbie’s first guess
today=date echo $today
Eg. 2 This is the way to do it.
today=$(date) (old version today=`date`) echo $today
Syntax:
$(unix_command)
The mechanics of command substitution works as follows:
- Unix will run the command within the parentheses as if it were typed at the keyboard. The command may include options, command line arguments, or even be a script.
- Instead of being displayed on the screen, the standard output (STDOUT) of the command is substituted at the exact position of the call ($(unix_command)).
The command substitution may be made anywhere in a program; however, it is often used on the right-hand side of an assignment statement (to save the output in a variable), or within an echo statement.