Sie sind auf Seite 1von 61

UNIX Shell Scripting Basics

Course Objectives
Topic Name

When you have completed this topic, you should be able to

Understanding UNIX shell


scripts

explain what a shell script is.

Choosing a UNIX shell

distinguish between the major shell environments and select a shell based
on its characteristics.

Creating an executable file in


UNIX

create and run a simple shell program.

Writing a UNIX shell program

write a simple shell script.

UNIX command execution

manage the execution of UNIX shell commands.

Redirection in UNIX

redirect standard input and output and use file descriptors.

Substitution and patterns in


UNIX

use substitution and quoting to expand and match files and commands.

UNIX command syntax


reference

describe the syntax used to execute shell commands.

Using UNIX commands in a


script

write a shell script that uses the shell's command execution and
substitution capabilities.

Understanding UNIX shell scripts


Learning objective

After completing this topic, you should be able to explain what a shell script is.

1. Command-line processing

The UNIX shell is a command-line interpreter that processes each command or


combination of commands on a command line when you press Enter.
This example shows only a single command on the command line.
$ sort -r userlist
You can combine multiple commands on the same command line by creating a
composite command.
This example shows a composite command comprising the ls and less
commands.
$ ls -l | less
You can use a number of special characters in the command line. A semicolon (;),
for example, allows you to place more than one command statement in the same
command line. When you enter the code, the shell executes the preceding
commands only when it reaches the semicolon.
In this example, the shell executes the cp command statement and then the cat
command statement.
$ cp list list.bak; cat list.bak
Special characters you can use to manipulate commands in the command line
include

backslash (\)

greater than (>)

less than (<)

pipe (|)

ampersand (&)

backslash (\)
The backslash (\) character prevents the shell from treating another character as a
special character through a process called backslash escaping.
This allows you to split a command statement across multiple lines. When you place the
backslash at the end of a line and then press Enter, you can continue the statement on
the next line. The backslash prevents the shell from treating the Enter keystroke or new
line character as a special character.
This example shows a long echo statement carried across three lines.

The code for this is


$ echo Long pieces of text may not always fit onto a single \
> line of the command line interface, so it becomes \
> necessary to split them across multiple lines using \
> backslashes.
greater than (>)
The greater-than character (>) allows you to direct the standard output of a command to
a file or a device such as a printer instead of to the terminal screen.
This example will send the output of the ls command to a file called userdirs.
The code for this is
$ ls -l /usr/home > userdirs
less than (<)
The less-than character (<) allows you to send the contents of a file to a command as its
standard input.
This example sends input from a file called list to the sort command.
The code for this is
$ sort -d < list
pipe (|)
The pipe character (|) allows you to direct the output of one command to the input of
another command.
This example pipes the output from the cat command as input to the grep command for
further processing.
The code for this is
$ cat EasyNomad | grep 'South America'
ampersand (&)
An ampersand (&) character at the end of a command statement allows you to run
commands in the background.
This example specifies that the find command will run a long search process in the
background.
The code for this is

$ find 'EasyNomad' &


[1] 48748
$ EasyNomad
If you want to use special characters in command-line text without the shell
recognizing them as special characters, you have to enclose them in quotes or
precede them with a backslash (\).
This example shows an echo command in which the echo text contains an
ampersand. There's a backslash in front of the ampersand, which prevents the
shell from treating it as a special character.
$ echo Tours \& Accommodation
Tours & Accommodation
$

Question
How do you think the shell processes the contents of a command line in order to execute it?
Options:
1.
2.
3.
4.

By analyzing commands first and then proceeding to options and arguments


By dividing the command line into segments and processing each segment
By processing the command line from beginning to end, one character at a time
By processing the command line from beginning to end, one word at a time

Answer
When you execute a command line, the shell looks for spaces and special characters and
splits the command line into segments wherever these characters occur. It then processes
each segment in turn.
The segments into which the shell divides a command line are called tokens. To
execute a command line, the shell processes the first token and then each
subsequent token in turn.
To begin processing a token, the shell checks whether it's a keyword, an alias, or
an ordinary word.
If the token is a keyword that opens a substructure such as a function, conditional
statement, or bracketed group of commands, the shell processes the substructure
before moving on to the next token.
If a token is an alias, the shell replaces it with the command to which the alias is

mapped.
If a token is an ordinary word such as a command or a filename, the shell
processes it directly.
After comparing a token against the list of known keywords and aliases, the shell
processes it using several stages of expansion and substitution.
Expansion and substitution takes place in the following sequence:

brace expansion

tilde expansion

parameter substitution

command substitution

arithmetic substitution

word splitting

pathname substitution

brace expansion
In brace expansion, the shell looks for braces ({}) also called curly brackets in the
token. If braces are present, it expands their contents.
For example, the token b{all,ook} expands into ball book.
tilde expansion
In tilde expansion, the shell looks for tildes (~) in the token. If a tilde is present, it replaces
the tilde with the location of the current user's home directory.
For example, depending on the system configuration, the token ~vincep/file2 might
expand into /usr/home/vincep/file2.
parameter substitution
In parameter substitution, the shell checks whether the token is a variable name
preceded by a dollar sign ($). If it is, the shell replaces the token with the current value of
the corresponding variable.
For example, if the value of the SHELL parameter is /bin/ksh, the token $SHELL is
replaced with /bin/ksh.
command substitution
In command substitution, the shell checks whether the token is a command enclosed in
brackets and preceded by a dollar sign ($). If it is, the shell processes the command and
replaces the token with the command's output.
For example, the token $(type username) might be replaced with vincep.

arithmetic substitution
In arithmetic substitution, the shell checks whether the token is an arithmetic expression
enclosed in double brackets and preceded by a dollar sign. If it is, the shell evaluates the
expression and replaces the token with the result.
For example, the shell replaces the token $((72/9)) with 8.
word splitting
In word splitting, the shell examines those parts of the command line that have resulted
from previous stages of expansion and substitution. If any of these contain spaces or
special characters, it splits them into tokens for processing.
pathname substitution
In pathname substitution, the shell looks for wildcard characters in the token. If it finds
asterisks (*), question marks (?), or double slashes (//), it searches the current directory
for filenames that match these wildcards and substitutes them for the token.
For example, depending on the files in the current directory, the token f*.txt might
expand into fares.txt flights.txt funding.txt.
After performing expansion and substitution, the shell processes subsequent
tokens until it reaches the end of a command, denoted by a semicolon or a new
line character.
Then it matches the command against its list of known functions, built-in
commands, and pathnames.
Once the shell has identified which command it needs to execute, it executes the
command to produce output.
It then moves on to the next command, processing its tokens in the same way.

Question
Which special character is used to run a command in the background?
Options:
1.
2.
3.
4.

&
|
;
\

Answer
The ampersand symbol (&) is used to run a command in the background.

Option 1 is correct. The ampersand symbol (&) is used at the end of a command, to run a
job in the background. Jobs in the background are assigned a job id number. You can you
can use this number to foreground the job again.
Option 2 is incorrect. The pipe (|) special character allows you to use the output of the
command on the left of the pipe as input for the command on the right of the pipe.
Option 3 is incorrect. The semi-colon (;) is used to combine separate commands on the
same line. Commands on the right of the semi-colon are only interpreted once commands
on the left have been interpreted and executed.
Option 4 is incorrect. The backslash (\) is used to prevent special characters from being
interpreted in such a way that their literal values are used in stings. Also, you can continue
your command on a new line by typing a backslash before pressing Enter.

Question
Choose the code that contains an example of command substitution.
Options:
1.
2.
3.
4.

cat logfile | grep $(cat /etc/hostname)


cd ~/documents
echo server{1,2,3).easynomad.com > hosts
ls * | grep "easynomad"

Answer
The code $(cat /etc/hostname) is an example of command substitution. The contents of the
hostname file are used as a search term by the grep command.
Option 1 is correct. In this example of command substitution, the command cat
/etc/hostname is processed before the grep command is executed, so that its output can be
substituted into the grep command.
Option 2 is incorrect. This is an example of tilde substitution. The path ~/documents
expands to the documents folder in the home directory of the current user.
Option 3 is incorrect. This is an example of brace expansion. The code
server{1,2,3).easynomad.com is expanded as: server1.easynomad.com;
server2.easynomad.com; server3.easynomad.com.
Option 4 is incorrect. This is an example of filename substitution. The code ls * lists every
file in the current directory.

2. Command grouping

You can join commands on a command line in such a way that the second
command executes only if the first command has executed successfully.
For example, you can use a first command to check whether a file exists and a
second command to perform an operation on it if it exists.

Question
How do you think the shell knows whether a command has executed successfully?
Options:
1.
2.
3.
4.

Because the command terminates


Because the command's exit status is zero
Because the command's standard error output is null
Because the command's standard output contains no error messages

Answer
The shell knows that a command has executed successfully when the exit status of the
command is zero.
To make one command conditional on another, you join the commands using a
double ampersand (&&). The command after the && symbols executes only if the
command before the && symbols produces a zero exit status in other words, if it
executes successfully.
In this example, the ls command checks whether the userlist file exists. Because
it does exist, the ls command executes without errors ( so its exit state is zero.
This causes the sort command to execute.
$ ls userlist && sort userlist
userlist
BAKER, Daniel
CARUSO, Maria
GARZA, Teresa
LOGAN, Greg
MANEROWSKI, Sarah
NOVAK, Nicholas
NOVIALLO, Glen
OSWALD, Sam
PASCUCCI, Vince
REILLY, Molly
STROTHER, Tanya
WADE, Debora
$

If you delete the userlist file and run the command again, the ls command
encounters an error so its exit state is non-zero. Because the sort command is
conditional, the shell doesn't attempt to execute it.
$ ls userlist && sort userlist
ls: userlist: No such file or directory
$
You use a double pipe (||) to make a command conditional on the unsuccessful
execution of the previous command.
In such a case, the second command executes only if the first command has a
non-zero exit state.
In this example, the ls command looks for a file called userlist. If it fails to find the
file, the touch command creates it.
$ ls userlist || touch userlist
ls: userlist: No such file or directory
$
If the ls command executes successfully, this means that the file already exists.
In this case, the touch command doesn't execute.
$ ls userlist || touch userlist
userlist
$
You can group commands using braces ({}). The shell treats any command block
enclosed in braces as if it were a single command.
This allows you to redirect input and output to and from a group of commands.
In this example, the braces group the sort and grep commands into a code
block so that the shell sorts input and then extracts any lines containing the word
Mexico.
$ {sort | grep 'Mexico'}
You can redirect input and output to a command block as if it were a single
command. In this example, the code specifies the flights file as input and the
mex_flights file as output.
$ {sort | grep 'Mexico'} < flights > mex_flights
$

You can group commands using round brackets often called parentheses
instead of braces. This causes the shell to spawn a subshell and execute the
command block in the subshell.
Commands that execute in a subshell do not affect what's happening in the main
shell.
This allows you to define variables that exist only for the lifetime of the subshell,
and to change the working directory within the subshell without affecting the
parent shell.
$ (sort | grep 'Mexico') < massivefile > mex_info
$

Question
You want to create a file named hostname and containing the text easy1.easynomad.com.
However, you don't want to overwrite any existing file by that name.
Which line of code will enable you to do this?
Options:
1.
2.
3.
4.

cat hostname || echo easy1.easynomad.com > hostname


cat hostname && echo easy1.easynomad.com > hostname
cat hostname >> echo easy1.easynomad.com > hostname
cat hostname | echo easy1.easynomad.com > hostname

Answer
The use of the || ensures that the code that writes the output from the echo command to the
hostname file will only execute if the attempt to list the hostname file fails.
Option 1 is correct. You use the double pipe to make a command conditional on the
unsuccessful execution of a previous command.
Option 2 is incorrect. The && conditional execution symbol ensures that if the attempt to list
the hostname file succeeds, it will get overwritten.
Option 3 is incorrect. The >> redirector is used to append output to a file.
Option 4 is incorrect. The I symbol pipes the output from one command into another
command as input.

3. Storing commands in scripts

Command grouping is useful for executing relatively short command-line code


that you need to run only once.
However, you may need to run larger pieces of code that include several lines or
to use the same piece of code many times.
In such cases, it's advantageous to store the code in a file.
You can store blocks of shell commands in shell scripts.
The contents of shell scripts are stored as ordinary ASCII text.

Question
What do you think distinguishes shell script files from ordinary ASCII text files?
Options:
1.
2.
3.
4.

They contain commands


They have a specific filename suffix
They have an introductory line of code that defines them as scripts
You can execute them

Answer
Unlike ordinary ASCII text files, shell scripts contain commands, are executable, and have
an introductory line of code that defines them as scripts.
You can read and edit ordinary text files, but you cannot execute them. However,
you need to be able to execute shell scripts.
Therefore, you have to assign executable permissions on script files.
The first line in any shell script has to be a special line of code that specifies the
particular shell program in which the script must run.
This is necessary because some commands run differently in different shell
programs.
The shell identifier at the beginning of a shell script consists of a hash followed by
an exclamation point (#!) commonly called a shebang and the absolute
pathname of the shell program.
This example shows the first line of a script that uses the Korn shell.
#! /bin/ksh

This simple example of a script tests whether the directory /usr/shared/tours


exists. If it doesn't, the script creates it. Then it creates a file called tourlist inside
this directory and returns a message.
#! /bin/ksh
ls /usr/shared/tours || mkdir /usr/shared/tours
touch /usr/shared/tours/tourlist
echo tour directory and tourlist file created.
Once you've created a script and made it executable, you can use it as many
times as you like. You can execute it directly from the command line or you can
invoke it from inside other scripts.

Question
Identify the statements that correctly describe shell scripts.
Options:
1.
2.
3.
4.

Shell scripts are ASCII text files


Shell scripts need to be compiled prior to execution
Shell scripts need to have executable permissions set
The first line of a shell script is used to identify the command interpreter

Answer
Shell scripts are ASCII text files that need to have executable permissions set. The first line
of a shell script identifies the command interpreter.
Option 1 is correct. Because shell scripts are simple ASCII text files, you can easily create
them in a text editor such as vi or emacs.
Option 2 is incorrect. Shell scipts are interpreted by the command interpreter, so they don't
contain binary code and aren't compiled.
Option 3 is correct. Because shell scipts are executed, either one or more of the owner,
group, or other executable permissions must be set.
Option 4 is correct. The first line of a shell script consists of a hash symbol followed by an
exclamation mark and the absolute path to the command interpreter that will be used to
execute the script. For example:
#!/bin/bash

Summary

You can use special characters to join commands on a single command line, to
redirect input and output, to run commands in the background, and to continue a
command over multiple lines. You can prevent the shell from recognizing a special
character by preceding it with a backslash. When you execute a command line,
the shell splits it into tokens and processes each token in turn.
You can group commands using braces or brackets, which cause the shell to treat
the commands as a single command. You can join two commands so that the
second command will execute only if the first command executes successfully or
only if it executes unsuccessfully.
You can store blocks of commands in a text file called a shell script and make this
file executable. You can execute shell scripts directly from the command line and
reuse them as often as necessary.

Table of Contents
| Top of page |
| Learning objective |
| 1. Command-line processing |
| 2. Command grouping |
| 3. Storing commands in scripts |
| Summary |
Copyright 2003 SkillSoft. All rights reserved.
SkillSoft and the SkillSoft logo are trademarks or registered trademarks
of SkillSoft in the United States and certain other countries.
All other logos or trademarks are the property of their respective owners.

Choosing a UNIX shell


Abstract

This article describes the distinguishing characteristics of each of the


major UNIX shell environments, enabling you to choose which shell is
most appropriate for a particular task.

The main shell families


There are several groups commonly called families of UNIX shell
programs. The shell families were developed by different groups of
developers for different purposes. The most important are the Bash shell,
the Korn shell, and the TC shell.

The Bourne and Bash shells


The Bourne shell, created by Steve Bourne at AT&T, is the shell from
which almost all modern UNIX shells are derived. It is still the most
widespread shell program. It's installed as /bin/sh and it is found in every
flavor of UNIX.
This makes it particularly good for writing shell scripts, because scripts
written for the Bourne shell will run on any UNIX system. You can add
further scripting functionality to this shell by using the awk language
interpreter and the sed stream editor within shell scripts.
However, the Bourne shell is no longer widely used as an interactive shell.
It has been largely replaced by the Bourne Again Shell. This shell is
usually installed as /bin/bash and is better known as the Bash shell. The
Bash shell was developed as part of the Gnu's Not UNIX (GNU) project. It
has since become the default shell for Linux.
The Bash shell is backwardly compatible with the Bourne shell for
scripting purposes, and it contains additional interactive features derived
from the Korn and C shells. For example, it provides a command-line
history buffer. The up and down arrow keys allow you to scroll backwards
and forwards through the command history. The Bash shell also allows
you to edit a current command using the arrow keys and a mouse. These

command-line editing features make it a user-friendly shell that is easy for


beginners to learn.

The C and TC shells


The C shell, created at Berkeley by William Joy, uses syntax similar to
that of the C programming language. This was meant to be useful for shell
scripting, but it has never been widely used for that purpose. However, it
was the first UNIX shell to feature a command history buffer, and so
became popular as an interactive shell.
Unlike the Bash shell, the C shell does not allow users to scroll through
the command history buffer. Instead, each previously executed command
has an event number. Because of this cumbersome system and the fact
that it isn't compatible with the Bourne shell, the C shell has mostly been
displaced by other shells.
The TC shell is an updated version of the C shell that allows commandline editing in two modes, one resembling the vi editor and the other
resembling emacs. However, it has retained the drawbacks of the C shell,
including incompatibility with the Bourne shell.

The Korn shell


Like the Bourne shell, the Korn shell was developed at AT&T. It uses the
same syntax as the Bourne shell and is compatible with it, but it includes
enhanced scripting features similar to those of the TC shell. For example,
it allows command-line editing in vi and emacs mode. It's usually installed
as /bin/ksh.
The original version of the Korn shell is called ksh88 and was written by
Dave Korn. There is also an updated version called ksh93, with improved
scripting features. Independent software enthusiasts have created a clone
of ksh93 called the Public Domain Korn shell (pdksh). This open-source
version provides all the functionality of the Korn shell and also allows
users to scroll through the command history buffer.

POSIX shells
The Portable Operating System Interface (POSIX) 1003.2 is a standard
aimed at ensuring compatibility between UNIX shells. Both the Bash shell
and the ksh93 version of the Korn shell satisfy the POSIX standard. There

is also an updated version of the Bourne shell that meets the POSIX
standard.

Shell features
The following table compares the interactive features and scripting
features of the Bourne shell, the Bash shell, the Korn shell, and the TC
shell.

Features of the four main UNIX shells


Feature

Bourne shell
(sh)

Korn shell
(ksh)

Bash shell
(bash)

TC shell
(tcsh)

Job control

Aliases

Shell functions

Standard input/output redirection

Directory stacks

Command histories

Command-line editing (vi/emacs)

Username lookup

Login and logout watching

Filename, username, and hostname


completion

History completion

Fully programmable completion

Co-processes

Built-in arithmetic evaluation

Transparent following of symbolic


links

Periodic command execution

Customizable prompts

Spelling correction

Automatic mailbox checking

Noninteractive, non-login startup files N

Bypass of user startup files

Features of the four main UNIX shells


Feature

Bourne shell
(sh)

Korn shell
(ksh)

Bash shell
(bash)

TC shell
(tcsh)

Specifiable startup files

List variables

Full signal trap handling

File noclobber ability

Local variables

The Bourne shell has none of the advanced interactive and scripting
features of the other shells. Its value lies in the fact that it's available in
every flavor of UNIX and it is therefore useful for portability.
The features of the Bash shell such as history completion make it
especially useful for interactive use. By contrast, the Korn shell's features
make it more suitable for writing and running shell scripts. For example, it
supports list variables and co-processes, which the Bash shell does not.
The TC shell shares many of the features of the Korn and Bash shells,
and it supports additional features such as spelling correction and login
watching. However, it lacks some of the scripting features of the other
shells, such as shell functions and local variables.

Summary
The most popular shell environments are the Bourne shell, the Bash shell,
the Korn shell, and the C shell. The Bourne shell is found on all UNIX
systems, so it's a good shell for writing scripts that need to be compatible
with diverse systems. The Bash shell is a version of the Bourne shell that
includes additional features for interactive use.
The C and TC shells use similar syntax to that of the C programming
language. They're useful for scripting but are incompatible with the
Bourne shell.
The Korn shell is an extension of the Bourne shell that includes the
enhanced scripting features of the C shell.
The Portable Operating System Interface (POSIX) is a standard aimed at
ensuring compatibility between UNIX shells. The Bash and Korn shells

comply with the POSIX standard. There is also a version of the Bourne
shell called the POSIX shell that has been updated to meet the POSIX
standard.

Table of Contents
| Top of page |
| Abstract |
| The main shell families |
| Shell features |
| Summary

Exercise: Writing a UNIX shell program


A note about exercises

This exercise is designed for practice use and does not contain new
learning content. If your computer doesn't have an application or
applications required to carry out the exercise tasks, or if you would
prefer to perform the exercise at another time, you can proceed to the
next topic.
Scenario
You currently use a text file as a signature file for your e-mail
messages. It contains your name, job description, and contact details.
You decide to liven it up a little by writing a script that customizes it
with a different message every day.

Exercise
Your assignment for this exercise is to write a script that customizes
your e-mail signature file called mysig with a random message.
You generate the messages using the fortune command, which
outputs a random snippet of wisdom each time you run it. The
fortune program is located in /usr/games. You don't need to supply
any options or arguments to the fortune command.
You need to incorporate the fortune message in your signature file.
You need to use the cp command to make a temporary copy of mysig
called dailysig. This file prevents a buildup of previous fortune
messages by storing a single message for each day only. Finally, you
append the output from fortune to dailysig by redirecting to dailysig.
The shell you're using for this script is the Korn shell, which is located
at /bin/ksh.

Task list
Number Instructions
1

Write a script for the Korn shell that uses the fortune and cp commands as well as output redirection to customize
with a random message.

Review your solution and, when you are satisfied with it, open the
solution page.

#!/bin/ksh
cp mysig dailysig
/usr/games/fortune>>dailysig

Table of Contents
| Top of page |
| Scenario |
| Exercise |
Copyright 2009 SkillSoft. All rights reserved.
SkillSoft and the SkillSoft logo are trademarks or registered trademarks
of SkillSoft in the United States and certain other countries.
All other logos or trademarks are the property of their respective owners.

| Print | Contents | Close |

UNIX command execution


Learning objective

After completing this topic, you should be able to manage the execution of UNIX
shell commands.

1. Using the command line


In UNIX, shell programs provide an interface between users and the kernel the
core of the operating system.
You interact with the kernel by entering commands at the shell prompt.
It's possible to enter several commands at once. In this case, you separate each
command using a semicolon (;).
The code shown here redirects the output of the ls command to a file called
listing, and then uses the cat command to display the contents of the file.
Because the two commands are separated by a semicolon, they run
consecutively.
$ ls -l /home > listing ; cat listing
lrwxrwxrwx 1 root wheel 9 Oct 30 13:53 /home -> /usr/home
$
If you end a line of code with a backslash (\), pressing Enter will move you to a
new line and allow you to continue entering commands. You can continue to do
this over multiple lines.
When you run the commands, the shell will execute your code as if it were one
long line, ignoring the backslash characters.
You use backslash characters for improved readability.
$ echo This is a very long line of \
> text, wrapped with a backslash
This is a very long line of text, wrapped with a backslash
$

Question

Most shell commands behave as filters they can take data as input, process it, and
provide output. Because of this behavior, you can chain commands together, piping the
output of one command into the input of another command.
You do this using the pipe character (|).
See if you can pipe the output of the ls -l command to the less command.

$ MISSING CODE

Answer
You type ls -l | less to pipe the output of the ls -l command to the less command.
Sometimes you may want to run commands in the background, especially if
they're likely to take a long time to complete. Background commands use idle
CPU time only, allowing you to get on with other things.
You can background any command by suffixing it with an ampersand character
(&). The code shown here will run a script called myscript.sh in the background.
$ ./myscript.sh &
[1] 34030
$

Question
Which statements about using the command line are true?
Options:
1.
2.
3.
4.

You use a backslash (\) to wrap commands across multiple lines


You use a forwardslash (/) to prevent special characters being interpreted
You use an ampersand (&) to run commands in the background
You use a semi-colon (;) to separate commands that execute consecutively

Answer
You use the backslash to make long commands more readable, the semi-colon to enter
consecutive commands on the same line, and the ampersand to run commands in the
background.
Option 1 is correct. Provided you precede it with a backslash, you can use the Enter key to
continue long commands on a new line. The shell will run your command as one long line,
ignoring the backslashes.

Option 2 is incorrect. The forwardslash does not prevent special characters from being
intepreted. It is used in the syntax for describing the filesystem.
Option 3 is correct. The ampersand allows you to run commands in the background on idle
processor cycles, leaving you free to continue working in your current session.
Option 4 is correct. You can use the semi-colon to combine commands that execute
consecutively on a single command-line. This is useful when the first command will take a
long time to complete.

2. Conditional execution
Conditional execution is a programming strategy that allows you to specify
different actions based on the outcome of an initial operation.
For example, you could create a shell script that checks the size of a log file and
then backs it up only if it is larger than a certain size.
Regardless of their type or function, most UNIX commands return an exit status
number to the shell when they've completed executing. The exit status indicates
whether a command executed successfully.
If a command executed successfully, it returns a value of 0 to the shell. Greater
values indicate an error of some sort.
Although you never see exit statuses at the shell prompt, you can use them to
include conditional decisions in your shell scripts.
Most shells provide at least the following two pairs of operators for performing
conditional execution based on exit status values:

double pipe (||)

double ampersand (&&)

double pipe (||)


If you separate two commands with two pipe characters (||), the second command will
execute only if the first command returns an error a non-zero exit status.
double ampersand (&&)
If you separate two commands with two ampersand characters (&&), the second
command will execute only if the first command exits successfully returning a zero exit
status.
It's possible to combine conditional execution operators to produce complex code.

For example, in the syntax shown here, the second command executes only if the
first command fails. And if the second command fails, the third command will not
run.

Question
Identify the statements that correctly describe conditional execution.
Options:
1. A non-zero exit status indicates that a command did not execute successfully
2. An exit status of 0 indicates that a command completed successfully
3. Conditional execution allows you to choose an action based on the exit status of a
command
4. Conditional execution allows you to choose what code to run based on the output
of a command

Answer
A non-zero exit status indicates that a command did not execute successfully, while an exit
status of 0 indicates that it did complete successfully. Conditional execution allows you to
choose an action based on the exit status of a command.
Option 1 is correct. Any non-zero exit status is a failed command. The range of possible
non-zero values for the exit status depends on the command that you execute, and the shell
you use.
Option 2 is correct. If the last command to execute completed successfully, the value of the
$? Variable, in which the exit status is stored, will be 0.
Option 3 is correct. Depending on the conditional operator you use, code will execute only if
the previous command executes successfully, or only if the previous command fails.
Option 4 is incorrect. You can use the test command to return an exit status after testing for
a particular value, but conditional execution only operates on the exit status of commands,
not their results.

Question
You are creating a script that writes to the filesystem, and you don't want to alter any
existing files.
Which commands are safe to use?
Options:

1.
2.
3.
4.

ls
ls
ls
mv

hosts
hosts
hosts
hosts

&& touch hosts


|| touch hosts
; touch hosts
oldhosts && cat oldhosts && touch hosts

Answer
The || operator ensures that the hosts file is not overwritten if it already exists. You use the
&& operator to ensure that a new hosts file is only created if the command to rename the
original succeeds.
Option 1 is incorrect. The ls hosts command will have an exit status of 0 if the host file
exists, and the && operator will cause the hosts file access and modification times to be
updated.
Option 2 is correct. The || operator will execute if the hosts file doesn't exist and the ls
command returns a non-zero exit status. This will cause the touch command to execute and
create a new hosts file.
Option 3 is incorrect. The ; operator merely allows consecutive execution of commands.
The execution of the command to overwrite the hosts file is not dependant on the exit status
of the command listing the host file.
Option 4 is correct. It is safe to overwrite the hosts file if the command that renames the
original file, as well as the command that prints the contents of the renamed file, complete
successfully.
.
command 1 || command 2 && command 3

Question
Let's say that you want to create a command that will check for the existence of a log file. If
the file exists, the log file should be copied to a backup directory. If the copy operation fails,
the system should send an e-mail to the root user.
See if you can type an operator in the first blank space that will back up the log file if it
exists.

$ ls -l /var/log/mylog MISSING CODE


cp /var/log/mylog /backup/mylog \
MISSING CODE mail -s "Error" root
< errmsg.txt

Answer
You use the && operator to run the cp /var/logs/mylog /backup/mylog command if
the ls /var/logs/mylog command locates a log file.

Question
See if you can complete the code shown here to send an e-mail to the root user if the copy
operation fails.

$ ls -l /var/log/mylog && cp
/var/log/mylog /backup/mylog
> MISSING CODE mail -s "Error" root
< errmsg.txt

Answer
You use the || operator to execute the mail root@localhost "copy operation
failed" command if the copy operation returns a non-zero exit status.

3. Grouping commands
Conditional execution operations are based on the exit status value of a single
command you can't have more than one command on either side of a
conditional operator.
This behavior is sufficient for simple tasks, but often you'll need to base
conditional execution on the result of a series of commands. You achieve this
using grouping.
You can enclose a series of commands in brackets to create a code block. The
shell will treat a code block as if it were a single command ( it will return one exit
status value for the entire block, rather than for each individual command that the
block contains.
This allows you to create far more complex commands and shell scripts.
You can group commands using the following two types of brackets:

braces ({})

round brackets (())

braces ({})

You can use braces ({}) to create blocks of code that will execute in your current shell.
round brackets (())
You can use round brackets (()) to create blocks of code that will execute in a subshell ( a
new shell program spawned from the shell that you're running.
The advantage of running commands in a subshell ( by grouping them using
round brackets ( is that subshells have their own environment variables. As a
result, any radical environment changes that take place during the running of a
code block don't affect the shell you started with.

Question
Which statement about the line of code shown here is true?
(cd /etc ; cat hosts) && ls

$ (cd /etc ; cat hosts) && ls


Options:
1. The code in parentheses executes within a subshell
2. The ls command will list the contents of the /etc directory
3. The ls command will execute on condition that the cat hosts command is
successful
4. The code in parentheses is a comment

Answer
Code within parentheses is executed in a subshell.
Option 1 is correct. Code within parentheses is run as a separate process in a subshell. You
can set local environment variables within the subshell without effecting your main shell
session.
Option 2 is incorrect. The variable that stores the current working directory for the shell in
which the ls command is executed is not affected by the command to move to the /etc
directory in the subshell.
Option 3 is incorrect. The execution of the ls command is conditional on the successful
completion of the entire block of code within parentheses.
Option 4 is incorrect. You can include comments in shell scripts by preceding each line of
comments with the # symbol.

Question

Identify the operators that allow you to group commands in code blocks.
Options:
1.
2.
3.
4.

[]
{}
()
;

Answer
You use the parentheses () and the braces {} operators to group commands in code
blocks that return a single exit status.
Option 1 is incorrect. The [] symbols are used by the shell in pattern matching operations
to specify character ranges.
Option 2 is correct. The {} symbols group commands into a single code block for execution
in the current shell.
Option 3 is correct. The () symbols group commands into a code block that is executed in a
subshell. This is useful if you want to avoid altering environment variables in your current
shell, for instance.
Option 4 is incorrect. The ; symbol is used to enter multiple commands on the same line.
However, the commands are executed in sequence, not as a code block.

Question
Suppose that you're in /home/gregl and you need to execute the code shown here. It looks
for a specific log file, and if the file exists a message displays.
What do you think your current working directory will be when the code has finished
executing?

$ { cd /var/log ; ls mylog } /
&& echo "Found the log file"
Options:
1. /var/log
2. /home/gregl
3. /usr/home

Answer

After the command runs, your current working directory will still be /home/gregl.
Option 1 is incorrect. The command that changes the directory to /var/logs runs in a
subshell. To run the code in the current shell, thereby changing the current directory, you
need to remove the braces, as shown here:
cd /var/log ; ls mylog && echo "Found the log file"
The command that changes the current working directory to /var/log is part of a code
block enclosed in brackets (()), so it will execute in a subshell. As a result, it has no effect on
the current shell you're in.
Option 3 is incorrect. At no point does any code change the directory to /usr/home either
in the current shell or the subshell so this can't be the current directory.

Summary
The shell's command line provides an interface between users and the UNIX
kernel. You can separate commands using a semicolon (;), continue them on new
lines using a back slash (\), and plug them into each other using a pipe (|).
You can use conditional operators to specify that commands execute based on
the exit status of other commands. You use two ampersand characters (&&) to
specify that a command run only if a previous command was successful, and two
pipe characters (||) to specify that a command run only if a previous command
failed.
You can group commands into code blocks to specify that the shell return one exit
status for the entire block. You use braces ({}) to specify that code execute in the
current shell, and round brackets (()) to specify that code execute in a subshell.

Table of Contents
| Top of page |
| Learning objective |
| 1. Using the command line |
| 2. Conditional execution |
| 3. Grouping commands |
| Summary |
Copyright 2003 SkillSoft. All rights reserved.
SkillSoft and the SkillSoft logo are trademarks or registered trademarks

of SkillSoft in the United States and certain other countries.


All other logos or trademarks are the property of their respective owners.

| Print | Contents | Close |

Redirection in UNIX
Learning objective

After completing this topic, you should be able to redirect standard input and output,
and use file descriptors.

1. Using standard I/O redirection


Most UNIX commands behave as filters they can take input, process it in some way,
and provide output. A shell usually sends this output to the screen, but you can
redirect it to provide advanced functionality.
A common example of redirection is the use of the pipe operator (|) to plug the output
of one command directly into the input of another command. However, redirection
most often involves writing to and reading from files.
You can perform redirection with files by preceding a filename with one of the
following operators:

greater than (>)

less than (<)

two greater than symbols (>>)

greater than (>)


You use the > operator with a filename to redirect the output of a command to a file.
If the file doesn't exist, the shell will create it. If it exists, the shell will overwrite it.
less than (<)
You use the < operator with a filename to redirect standard input from a file. For
example, when using the mail command to send e-mail, you can redirect input from
a file you have previously prepared, rather than having to type your message at the
shell prompt.
two greater than symbols (>>)
You use the >> operator with a filename to redirect the output of a command to a
file, appending the new data if the file already exists. This is useful for creating log
files.
If you use a lot of file redirection in your scripts, it's quite easy to overwrite existing
files accidentally. To prevent this, most shells implement the noclobber environment
variable.

When set, noclobber prevents file overwriting through redirection but not through
the execution of commands such as cp or rm. You enable noclobber by typing set
-o noclobber, as shown here.
If you want to overwrite output files protected by noclobber, you can use the >|
operator to do this.
$ set -o noclobber
$

Question
Let's say that you want to send e-mail to a user called vincep. You've used the
vi editor to type the body of the e-mail, and you've saved it to a file called
email.txt.
See if you can complete the code shown here to redirect input from the
email.txt file rather than from standard input.

$ mail s "Guess what"


vincep@localhost MISSING CODE
email.txt

Answer
You use the < operator to redirect input from a file rather than from standard
input.
You send the mail, and the shell reads the e-mail body from the text file you've
specified.
$ mail s "Guess what"
vincep@localhost < email.txt
$

Question
Let's say you're using the man command to find out about the exec command.
You'd like to dump the information to a file so that you can print it later.
See if you can complete the command shown here to dump the output of the
command to a file called exec.txt.

$ man exec MISSING CODE exec.txt

Answer
You use the > operator to redirect standard output to a file rather than to the
screen.
The shell dumps the output of the man exec command to a text file. Because you've
redirected the output, you don't see it echoed to the screen.
$ man exec > exec.txt
$

Question
Match the redirection operators to the descriptions of their function.
Options:
1. >
2. <
3. >>
Targets:
A.
Used to append output from a command to a file
B. Used to redirect output from a command to a file
C. Used to specify a file as input for a command

Answer
You use the > operator to redirect the output from a command to a fle, the <
operator to use a file as input for a command, and the >> operator to append
the output from a command to an existing file.
You can use redirection to document your system by redirecting the output
from commands to a file, as in this example, which records the network
interfaces configured for a system: ifconfig a > network.txt
Several UNIX commands accept files as input. For instance, you can redirect a
text file called report.txt to the mail utility and send it to Fred with the following
command: mail Fred < report.txt
Appending command output to an existing file is useful for troubleshooting.
Scheduling regular execution of the following command enables you to

monitor which kernel modules are loaded on a Linux system: lsmod >>
/var/modules.log

2. File descriptors
File descriptors are files usually with numeric filenames ( on disk that point to
input/output (I/O) objects, such as the keyboard, the screen, or other files. You can
think of them as placeholders.
By using file descriptors, processes don't have to interact mechanically with the I/O
objects that the descriptors represent the kernel handles these mechanics.
Any running process can expect at least the three following default file descriptors to
be available:

0
Descriptor 0 is also known as standard input. It's normally mapped to the keyboard.
Processes look to this descriptor for user input.
1
Descriptor 1 is also known as standard output. It's normally mapped to the screen,
although when UNIX was created it was mapped to a printer.
Processes write command output to this descriptor, and the output then appears on
your screen.
2
Descriptor 2 is also known as standard error. It's normally mapped to the screen, but
when UNIX was invented it was mapped to a dedicated printer.
Processes write error messages to this descriptor, and the messages then appear
on your screen.
Processes can also create their own descriptors, usually for interacting with files.
You can redirect file descriptors in a similar way to performing ordinary redirection,
using the following syntax where n is a file descriptor:

<&n

>&n

n< filename

n> filename

n>> filename

n>| filename

<&n
You use <&n to redirect standard input from another descriptor. For example, you
could type <&2 to feed standard error into standard input.
>&n
You use >&n to redirect standard output to another descriptor. For example, you
could type >&2 to send standard output into standard error.
n< filename
You use n< with a filename to redirect a descriptor from the specified file.
n> filename
You use n> with a filename to redirect a descriptor to the specified file. As with
ordinary redirection, this will overwrite an existing file. To change this default
behavior and not have the file overwritten, set the noclobber variable, using the
set noclobber command.
n>> filename
You use n>> with a filename to redirect a descriptor to the specified file. This will
redirect to a file but, as with ordinary redirection, this will append to an existing file.
n>| filename
You use n>| with a filename to redirect a descriptor to the specified file, overriding
the noclobber variable if this has been set.

Question
Identify the true statements about performing descriptor redirection.
Options:
1. You use 2>| to ensure that existing files aren't overwritten by redirected
standard error
2. You use 2> to redirect standard error to a file
3. You use >&2 to redirect standard output to standard error
4. Use 1> to redirect standard output to a file

Answer
You use >&2 to redirect standard output to standard error, you redirect
standard error with 2>, and you redirect standard output to a file with 1>.

Option 1 is incorrect. In fact, this option allows you to overwrite existing files
with standard error.
Option 2 is correct. This is useful for for printing error messages.
Option 3 is correct. If your standard error is connected to a printer instead of
the display, this would be a quick way of printing command output.
Option 4 is correct. Instead of the output going to the screen it can be
redirected to a file using 1>

Question
Let's say that you want to use the find command to locate reports, and you
want to redirect both standard output and standard error to text files.
See if you can complete the first part of the code shown here to redirect
standard output to a text file called output.txt.

$ find / -name "report*" MISSING CODE


output.txt MISSING CODE error.txt

Answer
You type > to redirect standard output to a file.

Question
See if you can complete the code shown here to redirect standard error to a
file called error.txt.

$ find / report* 1> output.txt


MISSING CODE error.txt

Answer
You type 2> to redirect standard error to a file.

Question
Match each standard file descriptor value to its name.
Options:

1. 0
2. 1
3. 2
Targets:
A.
Standard error
B. Standard input
C. Standard output

Answer
The file descriptor for standard input has a value of 0, the descriptor for
standard output has a value of 1, and the descriptor for standard error has a
value of 2.
Standard input is associated with file descriptor 0, and is usually mapped to
the keyboard. Typing commands with a keyboard is the most common way of
interacting with the shell.
Standard output is usually mapped to the screen. Most programs use standard
output to print usage messages or the results of commands.
Standard error is associated with file descriptor 2, and is usually mapped to
the screen but it is sometimes useful to map it to a printer, to record errors.

3. Scripting with redirection


Sometimes, for convenience, you may want to pass multiple lines of input to a
command. You do this using a here document.
Here documents make it possible to give batch input to a command to pass the
command a list of things you want it to do.
You can use here documents using either of the following two syntax forms:

command << terminator [input ]

command <<- terminator [input ]

command << terminator [input ]


When you use the syntax command << terminator [input], the shell executes the
command and passes it the input you specify ( line by line, until it reaches the word
or character you've specified as a terminator.
command <<- terminator [input ]

When you use the syntax command <<- terminator [input], the shell executes the
command and passes it the input you specify ( line by line, until it reaches the word
or character you specified as a terminator.
The trailing dash in the syntax causes all leading tabs in the subsequent input to be
stripped.
.
Let's say that you want to automate a telnet session to e-mail yourself some data off a
remote machine. You begin by setting up the telnet command with a here document,
using the word END as a terminator.
You press Enter, and the shell waits for further input.
$ telnet << END
>
The first thing that a telnet session needs is the address of the target machine
( 190.100.2.3 in this case. So you enter the full command to open a session to that
machine and then press Enter.
$ telnet << END
> open 190.100.2.3
You know that the remote machine will require a username and password, so you
type them on the next line.
In this case, your username is "gregl" and your password is simply "password".
Then you press Enter.
$ telnet << END
> open 190.100.2.3
> gregl password
The remote system should have logged you on by this point in the script, so you enter
the commands you need to fetch the file you want. You also enter the quit command
to end the telnet session.
You press Enter after each command.
$
>
>
>

telnet << END


open 190.100.2.3
gregl password
mail s "remote userlogs" gregl@190.100.2.1 <

/var/log/userlog
> quit
To finish and execute the here document, you enter the terminator that you specified
to begin with ( in this case, the word END and you press Enter.
The shell executes the telnet command and feeds it the here document line by line.
$ telnet << END
> open 190.100.2.3
> gregl password
> mail s "remote userlogs"
gregl@190.100.2.1 < /var/log/userlog
> quit
> END

Question
Suppose that you're setting up a here document to run an ssh command,
using the word "END" as a terminator.
See if you can complete the code shown here to ensure that any leading tabs
in the here document will be stripped out.

$ ssh MISSING CODE Finish

Answer
You use the <<- operator to ensure that leading tabs are stripped out of here
documents.

Question
Which statements about here documents are correct?
Options:
1.
2.
3.
4.

The <<- operator allows you to strip leading tabs from a here document
Here documents can be used to automate login processes
The first line of a here document is always a command.
The terminator in here documents is END

Answer

You use the <<- operator to strip leading tabs from lines in a here documents.
Here documents are often used to automate interactive logins and the first line
of a here document is always a command.
Option 1 is correct. Automatically stripping tabs from your here document
allows you to improve its legibility.
Option 2 is correct. Most interactive command line programs, such as telnet or
ftp, can be automated using here documents
Option 3 is correct. Here documents start with a command interpreter that
loads a command to read and execute the rest of the shell script.
Option 4 is incorrect. Although END is frequently used as a terminator in here
documents, you can use any string as a terminator.

Summary
Most UNIX commands behave as filters, accepting input and providing processed
output. You can redirect command output to a file, and you can redirect command
input from a file.
File descriptors are numeric placeholders for input/output (I/O) objects. The default file
descriptors present in any shell environment include standard input (0), standard
output (1), and standard error (2). You can redirect file descriptors.
Here documents provide a convenient way of sending batch input to a command.
They are most commonly used for setting up scripts for interactive commands such as
telnet.

Table of Contents
| Top of page |
| Learning objective |
| 1. Using standard I/O redirection |
| 2. File descriptors |
| 3. Scripting with redirection |
| Summary |
Copyright 2003 SkillSoft. All rights reserved.
SkillSoft and the SkillSoft logo are trademarks or registered trademarks

of SkillSoft in the United States and certain other countries.


All other logos or trademarks are the property of their respective owners.

| Print | Contents | Close |

Substitution and patterns in UNIX


Learning objective

After completing this topic, you should be able to use substitution and quoting to
expand and match files and commands.

1. Substitution and matching


You can use filename substitution when entering commands to specify groups of files
that you want to work with.
Filename substitution involves using wildcard characters either on their own, or with a
pattern fragment. The shell resolves a wildcard to a list of files, which it then passes to
the command you're trying to execute.
The wildcard characters that UNIX supports include

asterisk (*)

question mark (?)

asterisk (*)
You use the * wildcard to match a string of any length.
For example, if you specify w*, the shell will return a list of every file in your current
working directory with a name beginning with "w".
question mark (?)
You use the ? wildcard to match a single character.
For example, if you specify file0?, the shell might return a list containing file01
through file09 if these files existed.
You can specify limited lists of characters for filename substitution using square
brackets ([]), using one of the forms shown here:

[abc]

[a-d]

[a-ce-g]

[abc]

You use the form [abc] to perform substitution with any character that appears
between the square brackets.
For example, if you specify file0[147], the shell will return a list containing file01,
file04, and file07 if these files exist.
[a-d]
You use the form [a-d] to perform substitution with any character that appears in the
range between the square brackets.
For example, if you specify data_[a-c], the shell will return a list containing
data_a, data_b, and data_c if these files exist.
[a-ce-g]
You use the form [a-ce-g] to perform substitution with any character that appears in
any of the ranges between the square brackets. You can include any number of
ranges in this way.
For example, if you specify log[1-36-8], the shell will return a list containing
log1, log2, log3, log6, log7, and log8 if these files exist.

Question
See if you can complete the code shown here to retrieve a list of all the files in
the current directory that begin with a lowercase letter or a digit.

$ ls MISSING CODE

Answer
You type [a-z0-9]* or [0-9a-z]* to retrieve a list of all files that begin with
a lowercase letter or a digit.
In the filename substitution shown here, the square brackets hold two ranges a to z
and 0 to 9. The brackets are followed by an asterisk (*), which allows any type of
string to follow the specified ranges.
$ ls [a-z0-9]*
120415_log report1.txt report3.txt staffdata
120603_log report2.txt searchdata
$
You can perform reverse matching using the exclamation mark (!) character. For
example, the code shown here lists all files in the current directory that don't end in a
digit.

$ ls l *[!0-9]
120415_log report1.txt report3.txt staffdata
120603_log report2.txt searchdata
$
Occasionally, you may need to refer to a user's home directory in a script. You can
refer to a user's home directory without knowing their username using the tilde (~)
character.
This enables you to write scripts with path references that any user can run.
$ echo ~
/home/vincep
$
You can use the tilde (~) character in substitution in the following forms:

~user

~-

~+

~
The shell resolves a lone tilde to the value of the current user's $HOME environment
variable.
~user
The shell resolves ~user to the path of a specific user's home directory.
~The shell resolves ~- to the path of the previous directory you were working in.
~+
The shell resolves ~+ to the path of the current directory.

Question
Which commands use the tilde (~) correctly?
Options:
1.
2.
3.
4.

cd
cd
cd
cd

~
~$HOME
~~Fred

Answer
These commands all use tilde substitution correctly
Option 1 is correct. In this case, the command changes the directory to the
home directory of the current user.
Option 2 is incorrect. The tilde substitutes for the $HOME variable, so this
command wouldn't work.
Option 3 is correct. Using the tilde command in this context changes the
current directory to its previous value.
Option 4 is correct. In this circumstance, the tilde command changes the
current directory to the home directory of the user Fred.

Question
Match each filename substitution format with its description.
Options:
1.
2.
3.
4.

[abc]
[a-e]
*
?

Targets:
A.
Substitutes for any character in a list
B. Substitutes for any character in a range
C. Substitutes for any single character
D. Substitutes for zero or more characters

Answer
To substitute from a list of characters into a filename, you use the [abc]
format. You can also specify a range using the [a-e] format. The *
substitutes for any character zero or more times, while the ? matches any
single character.
The command ls file[abc] would use filename substitution to match and
list files named filea, fileb, and filec if they exist.

The command ls text.[a-e] matches and lists every file named text with a
suffix consisting of a period followed by a character in the range of letters from
a to e. In other words, text.a, text.b, text.c, text.d, text.e will be listed.
The command ls file* will match and list any file with a filename that starts
with file, including file123.
The command ls file? will match and list any file with a filename that starts
with file and has one additional character, such as file1 or filea if they
exist.

2. Command substitution
Command substitution allows you to use the output of one command as an argument
for another command.
You can perform command substitution using the syntax

$(command)

$(< filename)

$(command)
When you use $(command) as an argument for another command, the shell
executes the bracketed command first. It then passes this command's entire output
to the unbracketed command.
$(< filename)
When you use $(< filename) as an argument for a command, the shell reads the
specified file and passes its entire contents to the command.

Question
See if you can complete the command shown here to display a list of files that
belong to you, without knowing what your username is.

$ ls l | grep MISSING CODE

Answer
The $(whoami) command returns your current username, which the grep
command uses to filter the output of the ls l command.
The code shown here shows a list of the files in the current directory that you own.

$ ls l | grep $(whoami)
-rw-r--r-- 1 vincep vincep
-rw-r--r-- 1 vincep vincep
-rw-r--r-- 1 vincep vincep
-rw-r--r-- 1 vincep vincep
-rw-r--r-- 1 vincep vincep

9880
9372
73234
247416
451008

Feb 11 15:40 120415_log


Feb 11 15:41 120603_log
Jan 8 09:22 report1.txt
Jan 8 09:23 report2.txt
Jan 8 09:24 report3.txt

When you include a special character such as a wildcard or a pipe as part of an


argument for a command, the command does not interpret that character. Instead, the
shell resolves it and passes the output to the command as an argument.
If you intend a command to use a special character as an argument, you must prevent
the shell from interpreting it by quoting the character.
The code shown here displays an asterisk on the screen. Without the quotation
marks, the shell would have resolved the asterisk to a list of all the files in the current
directory.
$ echo '*'
*
$
Instead of quote marks, you can use backslash escaping to perform quoting. To do
this, you place a backslash (\) immediately before a special character. This instructs
the shell to pass the character literally to the command instead of trying to interpret it.
Backslash escaping is also useful for situations in which you need to pass an actual
quote mark as an argument.
The code shown here uses backslash escaping to print out the message, "'*' is a
special character."
$ echo \'\*\' is a special character
'*' is a special character
$

Question
If you need to pass special characters to a command in an argument, you
enclose them in quotes to prevent them from being interpreted.
Which commands use a suitable alternative method for escaping special
characters?
Options:
1. echo \$USER

2. echo $($)USER
3. echo $(< $)USER

Answer
You use the backslash to escape special characters.
Option 1 is correct. The backslash prevents the $ from being interpreted as a
special character, so $USER will be printed onscreen, rather than the value of
the $USER variable.
Option 2 is incorrect. The $(command) syntax allows you to pass the output
from a command as a parameter to another command.
Option 3 is incorrect. The $(< filename) syntax allows you to pass the
contents of a file as a parameter to a command.

3. Using substitution in a script


Let's say that you're a system administrator, and you're preparing a startup script that
will run each time a user logs in. You start the vi editor, go into insert mode, and begin
typing.

You begin the script by clearing the screen and you use command substitution to
greet the user using the whoami command.
#!/usr/local/bin/ksh
# Logon welcome script
clear
echo Welcome $(whoami)
You add a line that uses command substitution to display the current date.
#!/usr/local/bin/ksh
# Logon welcome script
clear
echo Welcome $(whoami)
echo The current date is $(date "+%d-%M-%Y")

Question
You want to display a list of all the reports in the user's home directory, but you
don't know what the user's username is.

Complete the code shown here to navigate to the user's home directory.

#!/usr/local/bin/ksh
# Logon welcome script
clear
echo Welcome $(whoami)
echo The current date is $(date "+%d-%M-%Y")
MISSING CODE

Answer
You type cd ~ to navigate to a user's home directory without knowing the
user's username.

Question
You use the ls command to list the contents of the user's home directory.
See if you can complete the code shown here to use the grep command to
filter the output of the ls command to show only those files whose names
begin with "report".

#!/usr/local/bin/ksh
# Logon welcome script
clear
echo Welcome $(whoami)
echo The current date is $(date "+%d-%M-%Y")
cd ~
ls -l | grep "MISSING CODE"

Answer
You type report* to have the command return all files that begin with
"report".
You test the script, and it runs successfully.
Welcome vincep
The date is 26-08-2003
You have the following reports:
-rw-r--r--1 vincep vincep 73235 Jan 8 09:22 report1.txt
-rw-r--r--1 vincep vincep 247416 Jan 8 09:23 report2.txt

Question

Identify the true statements about command substitution and wildcards.


Options:
1. Command substitution allows you to use the output from a command as
standard input for a second command
2. Command substitution allows you to use the output from a command as part of
the argument for another command
3. Wild cards are used to perform command substitution
4. Wild cards are used to perform filename substitution

Answer
You use command substitution to include the output from a command in an
argument to another command and you perform filename substitution with
wildcards.
Option 1 is incorrect. Redirecting standard output into the standard input of a
command is performed using the UNIX pipe facility.
Option 2 is correct. The command echo It is $(date), for instance,
provides the following output: It is Fri Aug 18 11:25:55 BST 2003.
Option 3 is incorrect. The shell only performs filename substitution with
wildcards. The command echo It is $(dat*) will yield a "command not
found" error message.
Option 4 is correct. Filename substitution provides a quick way of searching
large directories for files conforming to a specific pattern.

Summary
Filename substitution involves specifying groups of files to use as arguments for
commands. Most shells let you use wildcards like asterisk (*) or a question mark (?) in
filename substitution. The shell resolves a wildcard into a list of files that match
specified search criteria.
Similarly, you can perform command substitution to use the output of one command
as an argument for another command. The shell resolves the argument command first
and passes its output to the main command.
You can use any combination of filename substitution and command substitution
when you write shell scripts.

Table of Contents

| Top of page |
| Learning objective |
| 1. Substitution and matching |
| 2. Command substitution |
| 3. Using substitution in a script |
| Summary |
Copyright 2003 SkillSoft. All rights reserved.
SkillSoft and the SkillSoft logo are trademarks or registered trademarks
of SkillSoft in the United States and certain other countries.
All other logos or trademarks are the property of their respective owners.

| Print | Contents | Close |

UNIX command syntax reference


Abstract

This article serves as a quick reference for the most commonly used shell scripting
syntax.

Introduction
There are hundreds of UNIX commands that you can execute at the shell
prompt. Shells have their own built-in syntax that helps you to work more
effectively with existing commands by allowing you to perform functions like
plugging commands into each other and controlling the flow of execution.

Conditional execution operators


||
You use the double pipe operator in the form
command1 || command2
In the above syntax, the second command executes only if the first command
fails.

&&
You use the double ampersand operator in the form
command1 && command2
In the above syntax, the second command executes only if the first command
executes successfully.

Command grouping operators


{}

You can enclose multiple statements in braces ({}) to create a code block. The
shell returns one exit status value for the entire group, rather than for each
command in the block.

()
You can enclose multiple statements in round brackets to create a code block.
This code block functions in the same way as a code block enclosed in
braces, but runs in a subshell.

I/O redirection operators


>
You use this operator to redirect command output to a file. If the specified file
doesn't exist, the shell creates the file. If the file does exist, the shell
overwrites it with the command output unless the noclobber environment
variable is set.

>|
You use this operator to redirect command output to a file. If the specified file
doesn't exist, the shell creates the file. If the file does exist, the shell
overwrites it with the command output even if the noclobber environment
variable is set.

>>
You use this operator to redirect command output to a file. If the file doesn't
exist, the shell creates the file. If it does exist, the shell appends the new data
to the end of it.

<
You use this operator to redirect command input from a file.

File descriptor redirection operators


<&n

You use this operator to redirect standard input from file descriptor n.

>&n
You use this operator to redirect standard input to file descriptor n.

n< filename
You use this operator with a filename to redirect descriptor n from the
specified file.

n> filename
You use this operator with a filename to redirect descriptor n to the specified
file. Unlike ordinary redirection, this will not overwrite an existing file.

n>| filename
You use this operator with a filename to redirect descriptor n to the specified
file, overriding the noclobber environment variable if it is set.

n>> filename
You use this operator with a filename to redirect a descriptor to the specified
file. This will redirect to a file but, unlike ordinary redirection, this will append
to an existing file.

Filename substitution
*
You use the * wildcard to match a string of any length.

?
You use the ? wildcard to match a single character.

[abc] , [a-c] , [a-c1-3]


You use square brackets to match only characters that appear inside the
specified set. For increased convenience, you can specify multiple ranges.

!pattern
You use the ! operator with a pattern to perform a reverse match. The shell
returns only filenames that don't match the pattern.

Command substitution
$(command)
You use this form of command substitution to resolve a command and pass its
output to another command as an argument.

$(< filename)
You use this form of command substitution to pass the entire contents of a file
to a command as an argument.

Tilde substitution
~
You use the ~ operator to instruct the shell to return the value of the $HOME
variable.

~username
You use the ~ operator with a username to instruct the shell to return the full
path of a specific user's home directory.

~+
You use the ~+ operator to instruct the shell to return the full path of the
current working directory.

~You use the ~- operator to instruct the shell to return the full path of the
previous working directory you used.

Miscellaneous syntax
;
If you enter several commands on the same line, you need to separate the
commands with semicolons. The shell will execute each command
successively once you press Enter.

\
You use a backslash to allow you to press Enter and continue typing
commands on a new line. The shell will only begin executing your commands
when you press Enter on a line that doesn't end in a backslash. Using a
backlash in this way is known as backslash escaping.

&
You add a single ampersand at the end of a command to run that command
as a background process. This is useful for tasks that are likely to take a long
time to complete.

Summary
Shell programs can execute a wide range of UNIX commands, but they also
have built-in functions to help you use shells more effectively.
Most shells support standard operators for conditional execution, input/output
(I/O) redirection, file descriptor redirection, and command grouping. They also
allow you to perform filename, tilde, and command substitution.

Table of Contents
| Top of page |
| Abstract |
| Introduction |
| Conditional execution operators |

| Command grouping operators |


| I/O redirection operators |
| File descriptor redirection operators |
| Filename substitution |
| Command substitution |
| Tilde substitution |
| Miscellaneous syntax |

| Summary |

| Print | Contents | Close |

Using UNIX commands in a script


Learning objective

After completing this topic, you should be able to write a shell script that uses the
shell's command execution and substitution capabilities.

Exercise overview
In this exercise, you're required to complete a script that will perform a search for
certain types of files, output the search results to a file, and e-mail that file to the root
user.
If an error occurs, the script should display a message on the screen.
This involves the following tasks:

using code blocks

using substitution

using redirection and conditional execution

Task 1: Using code blocks


Let's say that you're the root user and that you're editing a script in the vi editor.

Step 1 of 1
You want the first two lines of the script to act as a distinct code block that
returns one exit value for both commands. The commands should execute in
the current shell.
Which type of brackets should you use to achieve this?

MISSING CODE ls -l report


MISSING CODE MISSING CODE
localreports ;
mail -s "local reports" root
MISSING CODE
localreports ; MISSING CODE
MISSING CODE echo
An error occurred during search operation

Options:
1.
2.
3.
4.

Round brackets (())


Square brackets ([])
Braces ({})
Less than and greater than signs (<>)

Result
You use braces ({}) to create a code block that will execute in the current shell.
Option 1 is incorrect. You use round brackets to perform command
substitution, as in the variable assignment command shown here:
DATE=$(date)
Option 2 is incorrect. You use the square brackets to enclose conditional
expressions, such as:
if [ $FEEDBACK = y ] then
echo "proceed"
else
exit
fi
Option 3 is correct. The syntax for a function a sequence of code that is
available to the shell into which it is read is:
function_name() {commands}
Option 4 is incorrect. The <> special characters are used to perform
redirection. They are also used as conditional operators (less-than and
greater-than) within conditional expressions.

Task 2: Using substitution


Step 1 of 1
Suppose that you want to use the ls command to search for all files that begin
with the word "report" and end in a number between 0 and 9.
Use substitution to complete the search criteria shown here.

{ ls -l report MISSING CODE MISSING CODE


localreports ;mail -s "local reports" root MISSING CODE l
ocalreports ; }
MISSING CODE echo
An error occurred during search operation

Result
You specify report[0-9] with the ls command to list all files that begin with
the word "report" and end in a number between 0 and 9.

Task 3: Using redirection and conditionals


Step 1 of 3
Suppose that you want to redirect the output of the ls command to a file
named localreports.
Type the symbol that will achieve this.

{ ls -l report[0-9] MISSING CODE localreports ;


mail -s "local reports" root MISSING CODE localreports ; }
MISSING CODE echo
An error occurred during search operation

Result
You use the greater than symbol (>) to redirect output to a file.

Step 2 of 3
In the second line of the script, you want to redirect the contents of a mail from
the localreports file.
Type the correct symbol to do this.

{ ls -l report[0-9] > localreports ;


mail -s "local reports" root MISSING CODE localreports ; }
MISSING CODE echo
An error occurred during search operation

Result
You use the less than symbol (<) to redirect input from a file.

Step 3 of 3
You want the last line of the script to execute only if the code block produces
an error.

Type the symbol that will do this.

{ ls -l report[0-9] > localreports ;


mail -s "local reports" root < localreports ; }
MISSING CODE echo
An error occurred during search operation

Result
You use the double pipe symbol (||) to execute a command only if the
preceding command ( or, in this case, a command block ( fails.
You've now successfully completed a script that will perform a search for specific files,
output the search results to a file named localreports, and e-mail the localreports file
to the root user. It will also display an error message if the code fails.
{ ls -l report[0-9] > localreports ;
mail -s "local reports" root < localreports ; }
|| echo
An error occurred during search operation

Table of Contents
| Top of page |
| Learning objective |
| Exercise overview |
| Task 1: Using code blocks |
| Task 2: Using substitution |
| Task 3: Using redirection and conditionals |
Copyright 2003 SkillSoft. All rights reserved.
SkillSoft and the SkillSoft logo are trademarks or registered trademarks
of SkillSoft in the United States and certain other countries.
All other logos or trademarks are the property of their respective owners.

Das könnte Ihnen auch gefallen