Main index

Introducing UNIX and Linux


Introduction to shells

Overview
Why do we need a shell?
Shell syntax
      Types of shell command
      Simple commands
      Pipelines
      Grouping commands
      Exit status
      List commands
Arithmetic
      Operators and functions
Making decisions
      The 'test' statement
            Operators used by 'test'
      The 'if' statement
Loops
      'For' loops
      'While' and 'until' loops
Searching for files
      Arguments to 'find'
Formatted output
      Arguments to 'printf'
Passing information to scripts
      Scripts with arguments
      Parameter expansion
Summary
Exercises

Shell syntax

Any computer language has a syntax - that is, a set of rules defining what you can write in the language, and what you are forbidden to write. The shell uses symbols and words in a very precise way. We will not attempt to give a formal definition of the shell's syntax here, but we will describe most of its features.

Recall that a script is a file containing commands the shell is able to interpret. If a script is two or three lines long, it is likely to be clear to anyone reading the file what the commands do, and therefore the purpose of the script. If a script is a hundred lines long, it will not be so easy to see what is happening. Not only will it be difficult for someone else reading your scripts but if you make an error while writing it, you may yourself find trouble discovering exactly where the error has occurred.

It is good practice to include comments in your scripts. These are messages the shell ignores - they are there merely for the benefit of anyone reading the scripts.

If you write a script, and include a # ('hash') symbol, then the rest of that line (including the #) is ignored by the shell (unless that # appears within quotes or is within a word). For instance, the following script

MESSAGE="Hello $LOGNAME"
echo $MESSAGE

causes a message to be displayed on the terminal screen. The next script does exactly the same thing, but has had comments included.

# This script prints a friendly message on standard output
# Written by Chris, 5 December 2001
#
# This script requires variable LOGNAME to be set
 
MESSAGE="Hello $LOGNAME" # Set MESSAGE to the message
echo $MESSAGE # ... and echo it to stdout

The sort of information that should appear in comments includes

  • who wrote the script,
  • what the script does,
  • when it was written, and
  • what the individual parts of the script do.

For very short scripts, this may appear rather trivial, but for longer scripts comments are essential, and you should get into the habit of commenting all your scripts. Comments only work in scripts, and will not work interactively, when you are giving the shell instructions from a terminal. Try creating a file (messagefile, say) containing the above script, and run it using:

sh messagefile

When the shell reads input, it reads the input line-by-line looking for commands, and each line is first of all stripped of comments. A command is normally terminated by the end of the line on which it appears, with the exception that if the end of the line is premature, and the shell knows you haven't completed typing in the command, it will recognise this and expect you to continue the command on the next line. If the shell is interactive, it will prompt you with a > (or whatever the value of PS2 is instead of >) to continue with a command that was started on the previous line. For instance, if you tried to echo a string and typed only one quote the shell would infer that you had not finished typing in the string, and that you would continue on the next line. Try it:

echo "Hello
Chris"
Hello
Chris

You can also try creating a file containing

echo "Hello
Chris"

and executing the file as a shell script. Remember that the only difference between a shell script (which is a file containing shell commands) and the commands you type in on your terminal, is where the input to the shell comes from. In the case of an interactive shell, such as your login shell, the shell commands are typed in by you at your terminal; when a script is run, the shell reads commands from the script file.

You can also terminate a command with the symbols & or ; so you can have several commands on a single line. If you separate them with semicolons they will run one after the other, as if you had written them on separate lines. If you separate them by ampersands, they will be sent to run in the background one after the other, and will therefore be executed concurrently. A semicolon terminates a command and causes it to be run in the foreground. Try the following:

date; sleep 5; date
date & uname & who &

A sequence of commands separated by semicolons or Newlines is called a sequential list, and a sequence separated by ampersands is an asynchronous list.


Copyright © 2002 Mike Joy, Stephen Jarvis and Michael Luck