Siêu thị PDFTải ngay đi em, trời tối mất

Thư viện tri thức trực tuyến

Kho tài liệu với 50,000+ tài liệu học thuật

© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

UNIX UNLEASHED PHẦN 2 doc
PREMIUM
Số trang
202
Kích thước
1.3 MB
Định dạng
PDF
Lượt xem
1254

UNIX UNLEASHED PHẦN 2 doc

Nội dung xem thử

Mô tả chi tiết

Part II — Hunt for Shells

What Is a Shell?

Bourne Shell

Korn Shell

C Shell

Which Shell Is Right for You? Shell Comparison

 10

o What Is a Shell?

 By Rick Rummel

 Introduction

 The Kernel and the Shell

 The Functions of a Shell

 Command Line Interpretation

 Program Initiation

 Input-output Redirection

 Pipeline Connection

 Substitution of Filenames

 Maintenance of Variables

 Environment Control

 Shell Programming

 Summary

10

What Is a Shell?

By Rick Rummel

Introduction

You can do many things without having an extensive knowledge of how they actually work. For

example, you can drive a car without understanding the physics of the internal combustion

engine. A lack of knowledge of electronics doesn't prevent you from enjoying music from a CD

player. You can use a UNIX computer without knowing what the shell is and how it works.

However, you will get a lot more out of UNIX if you do.

Three shells are typically available on a UNIX system: Bourne, Korn, and C shells. They are

discussed in Chapters 11, 12, and 13. In this chapter, you'll learn

 What a shell is

 What a shell does for you

 How a shell relates to the overall system

The Kernel and the Shell

As the shell of a nut provides a protective covering for the kernel inside, a UNIX shell provides

a protective outer covering. When you turn on, or "boot up," a UNIX-based computer, the

program unix is loaded into the computer's main memory, where it remains until you shut down

the computer. This program, called the kernel, performs many low-level and system-level

functions. The kernel is responsible for interpreting and sending basic instructions to the

computer's processor. The kernel is also responsible for running and scheduling processes and

for carrying out all input and output. The kernel is the heart of a UNIX system. There is one and

only one kernel.

As you might suspect from the critical nature of the kernel's responsibilities, the instructions to

the kernel are complex and highly technical. To protect the user from the complexity of the

kernel, and to protect the kernel from the shortcomings of the user, a protective shell is built

around the kernel. The user makes requests to a shell, which interprets them, and passes them on

to the kernel. The remainder of this section explains how this outer layer is built.

Once the kernel is loaded to memory, it is ready to carry out user requests. First, though, a user

must log in and make a request. For a user to log in, however, the kernel must know who the

user is and how to communicate with him. To do this, the kernel invokes two special programs,

getty and login. For every user port—usually referred to as a tty—the kernel invokes the getty

program. This process is called spawning. The getty program displays a login prompt and

continuously monitors the communication port for any type of input that it assumes is a user

name. Figure 10.1 shows a freshly booted UNIX system with six user ports.

Figure 10.1. An active system with no users.

When getty receives any input, it calls the login program, as shown in Figure 10.2. The login

program establishes the identity of the user and validates his right to log in. The login program

checks the password file. If the user fails to enter a valid password, the port is returned to the

control of a getty. If the user enters a valid password, login passes control by invoking the

program name found in the user's entry in the password file. This program might be a word

processor or a spreadsheet, but it usually is a more generic program called a shell.

Figure 10.2. A user logs in.

In the system shown in Figure 10.3, four users have logged in. Likewise, one user is in the

process of logging in, and one port has no activity. Of the four active users, two are using the

Bourne shell, one is using the Korn shell, and one has logged into a spreadsheet. Each user has

received a copy of the shell to service his requests, but there is only one kernel. Using a shell

does not prevent a user from using a spreadsheet or another program, but those programs run

under the active shell. A shell is a program dedicated to a single user, and it provides an

interface between the user and the UNIX kernel.

Figure 10.3. An active system.

You don't have to use a shell to access UNIX. In Figure 10.3, one of the users has been given a

spreadsheet instead of a shell. When this user logs in, the spreadsheet program starts. When he

exits the spreadsheet, he is logged out. This technique is useful in situations where security is a

major concern, or when it is desirable to shield the user from any interface with UNIX. The

drawback is that the user cannot use mail or the other UNIX utilities.

Because any program can be executed from the login—and a shell is simply a program—it is

possible for you to write your own shell. In fact, three shells, developed independently, have

become a standard part of UNIX. They are

 The Bourne shell, developed by Stephen Bourne

 The Korn shell, developed by David Korn

 The C shell, developed by Bill Joy

This variety of shells enables you to select the interface that best suits your needs or the one

with which you are most familiar.

The Functions of a Shell

It doesn't matter which of the standard shells you choose, for all three have the same purpose: to

provide a user interface to UNIX. To provide this interface, all three offer the same basic

functions:

 Command line interpretation

 Program initiation

 Input-output redirection

 Pipeline connection

 Substitution of filenames

 Maintenance of variables

 Environment control

 Shell programming

Command Line Interpretation

When you log in, starting a special version of a shell called an interactive shell, you see a shell

prompt, usually in the form of a dollar sign ($), a percent sign (%), or a pound sign (#). When

you type a line of input at a shell prompt, the shell tries to interpret it. Input to a shell prompt is

sometimes called a command line. The basic format of a command line is

command arguments

command is an executable UNIX command, program, utility, or shell program. The arguments

are passed to the executable. Most UNIX utility programs expect arguments to take the

following form:

options filenames

For example, in the command line

$ ls -l file1 file2

there are three arguments to ls, the first of which is an option, while the last two are file names.

One of the things the shell does for the kernel is to eliminate unnecessary information. For a

computer, one type of unnecessary information is whitespace; therefore, it is important to know

what the shell does when it sees whitespace. Whitespace consists of the space character, the

horizontal tab, and the new line character. Consider this example:

$ echo part A part B part C

part A part B part C

Here, the shell has interpreted the command line as the echo command with six arguments and

has removed the whitespace between the arguments. For example, if you were printing headings

for a report and you wanted to keep the whitespace, you would have to enclose the data in

quotation marks, as in

$ echo 'part A part B part C'

part A part B part C

The single quotation mark prevents the shell from looking inside the quotes. Now the shell

interprets this line as the echo command with a single argument, which happens to be a string of

characters including whitespace.

Program Initiation

When the shell finishes interpreting a command line, it initiates the execution of the requested

program. The kernel actually executes it. To initiate program execution, the shell searches for

the executable file in the directories specified in the PATH environment variable. When it finds

the executable file, a subshell is started for the program to run. You should understand that the

subshell can establish and manipulate its own environment without affecting the environment of

its parent shell. For example, a subshell can change its working directory, but the working

directory of the parent shell remains unchanged when the subshell is finished.

Input-output Redirection

Chapter 4, "Listing Files," introduced input-output redirection. It is the responsibility of the shell

to make this happen. The shell does the redirection before it executes the program. Consider

these two examples, which use the wc word count utility on a data file with 5 lines:

$ wc -l fivelines

5 fivelines

$ wc -l <fivelines

5

This is a subtle difference. In the first example, wc understands that it is to go out and find a file

named fivelines and operate on it. Since wc knows the name of the file it displays it for the user.

In the second example, wc sees only data, and does not know where it came from because the

shell has done the work of locating and redirecting the data to wc, so wc cannot display the file

name.

Pipeline Connection

Since pipeline connections are actually a special case of input-output redirection in which the

standard output of one command is piped directly to the standard input of the next command, it

follows that pipelining also happens before the program call is made. Consider this command

line:

$ who | wc -l

5

In the second example, rather than displaying its output on your screen, the shell has directed

the output of who directly to the input of wc. Pipes are discussed in Chapter 4.

Substitution of Filenames

Chapter 4 explained how metacharacters can be used to reference more than one file in a

command line. It is the responsibility of the shell to make this substitution. The shell makes this

substitution before it executes the program. For example,

$ echo *

file1 file2 file3 file3x file4

Here, the asterisk is expanded to the five filenames, and it is passed to echo as five arguments. If

you wanted to echo an asterisk, we would enclose it in quotation marks.

Maintenance of Variables

The shell is capable of maintaining variables. Variables are places where you can store data for

later use. You assign a value to a variable with an equal (=) sign.

$ LOOKUP=/usr/mydir

Here, the shell establishes LOOKUP as a variable, and assigns it the value /usr/mydir. Later,

you can use the value stored in LOOKUP in a command line by prefacing the variable name

with a dollar sign ($). Consider these examples:

$ echo $LOOKUP

/usr/mydir

$ echo LOOKUP

LOOKUP

Note for C-shell users. Assigning values to variables in the C-shell differs from the

Bourne and Korn shells. To assign a variable in the C-shell use the set command.

% set LOOKUP = /usr/mydir

Notice that spaces precede and follow the equal sign.

Like filename substitution, variable name substitution happens before the program call is made.

The second example omits the dollar sign ($). Therefore, the shell simply passes the string to

echo as an argument. In variable name substitution, the value of the variable replaces the

variable name.

For example, in

$ ls $LOOKUP/filename

the ls program is called with the single argument /usr/mydir/filename.

Environment Control

When the login program invokes your shell, it sets up your environment, which includes your

home directory, the type of terminal you are using, and the path that will be searched for

executable files. The environment is stored in variables called environmental variables. To

change the environment, you simply change a value stored in an environmental variable. For

example, to change the terminal type, you change the value in the TERM variable, as in

$ echo $TERM

vt100

$ TERM=ansi

$ echo $TERM

ansi

Note for C-shell users. C-shell assigns values to environment variables using the setenv

command.

% setenv TERM vt100

Chapter 11, "Bourne Shell," Chapter 12, "Korn Shell," and Chapter 13, "C Shell," contain more

information on customizing your environment.

Shell Programming

You've seen that the shell is used to interpret command lines, maintain variables, and execute

programs. The shell also is a programming language. By combining commands and variable

assignments with flow control and decision making, you have a powerful programming tool.

Using the shell as a programming language, you can automate recurring tasks, write reports and

you can even build and manipulate your own data files. The next three chapters discuss shell

programming in more detail.

Summary

The shell provides an interface between the user and the heart of UNIX—the kernel. The shell

takes command lines as input, makes filename and variable substitution, redirects input and

output, locates the executable file, and initiates programs. The shell maintains each user's

environment variables. The shell also is a powerful programming language.

 11

o Bourne Shell

 By Richard E. Rummel

 Shell Basics

 How the Shell Interprets Commands

 Entering Simple Commands

 Redirection of Input and Output

 Entering Multiple Commands on One Line

 Entering Commands Too Long for One Line

 Filename Substitutions on the Command Line

 Substitution of Variable Data

 Substituting the Results of Commands in a Command Line

 Escaping from the Special Characters

 Entering Data from the Shell

 Shell Options

 The Restricted Shell

 Changing Shell Options with set

 Variables

 Defining Your Own (User-Defined) Variables

 Conditional Variable Substitution

 Substituting Default Values for Variables

 Conditional Variable Substitution with Error Checking

 Positional Variables or Parameters

 Special Variables in the Bourne Shell

 Environment Variables

 Preventing Variables from Being Changed

 Making Variables Available to Subshells with export

 Shell Programming

 What Is a Program?

 A Simple Program

 The Shell as a Language

 Using Data Variables in Shell Programs

 Entering Comments in Shell Programs

 Doing Arithmetic on Shell Variables

 Passing Arguments to Shell Programs

 Decision Making in Shell Programs

 The if-then Statement

 Data Output from Shell Programs

 The if-then-else Statement

 Testing Conditions with test

 Testing Character Data

 Testing Numeric Data

 Testing for Files

 Combining and Negating test Conditions

 A Shorthand Method of Doing Tests

 The Null Command

 Displaying the Program Name

 Nested if Statements and the elif Construct

 Reading Data into a Program Interactively

 The case Statement

 Building Repetitions into a Program

 Repeating Within a while Loop

 Repeating Within an until Loop

 Processing an Arbitrary Number of Parameters with shift

 Repeating Within a for Loop

 Getting Out of a Loop from the Middle

 Structured Shell Programming Using Functions

 Handling the Unexpected with trap

 Conditional Command Execution with the And/Or Constructs

 Reading UNIX-Style Options

 Customizing the Shell

 Customizing the Shell with Environment Variables

 Changing Your Command-Line Prompt with PS

 Adding Command-Line Separators with IFS

 Checking Multiple Mailboxes with MAILPATH

 Automating Environment Changes

 Adding Your Own Commands and Functions

 Specialized Topics

 Debugging Shell Programs

 Grouping Commands

 Using the Shell Layer Manager shl

 Summary

11

Bourne Shell

By Richard E. Rummel

In this chapter, you learn how to get the most out of the Bourne shell, one of the most used of

the UNIX shells. You also learn how to store data in your own variables, how to customize your

environment with environment variables, and how to group commands together to form shell

programs.

Shell Basics

The Bourne shell was written by Stephen Bourne at Bell Laboratories, where UNIX was

originally developed. Because it is found on most UNIX systems, many software developers

work under the assumption that the Bourne shell is available on a UNIX system. This use does

not mean that it is the best shell, but simply that it is the most common. Other shells, most

notably the Korn shell, were written to enhance the Bourne shell, so shell programs written for

Bourne run under the Korn shell. In some literature, the Bourne shell is called the UNIX system

Version 7 shell.

How the Shell Interprets Commands

The first exposure most people have to the Bourne shell is as an interactive shell. After logging

on the system and seeing any messages from the system administrator, the user sees a shell

prompt. For users other than the super-user, the default prompt for the interactive Bourne shell

is a dollar sign ($). When you see the dollar sign ($), the interactive shell is ready to accept a

line of input, which it interprets. When the super-user logs in, he or she sees the pound sign (#)

as a prompt. It is a reminder that as super-user some of the built-in protections are not available

and that extra care is necessary in this mode.

NOTE: On UNIX systems the super-user, also referred to as root, is without restriction.

The super-user can write to any directory and can remove any file. File permissions do not apply

to the super-user. The password for the super-user is usually closely held by the system

administrator.

The shell sees a line of input as a string of characters terminated with a newline character, which

is usually the result of pressing Enter on your keyboard. The length of the input line has nothing

to do with the width of your computer display. When the shell sees the newline character, it

begins to interpret the line.

Entering Simple Commands

The most common form of input to the shell is the simple command, in which a command name

is followed by any number of arguments. In the example

$ ls file1 file2 file3

ls is the command and file1, file2, and file3 are the arguments. The command is any UNIX

executable. It is the responsibility of the command, not the shell, to interpret the arguments.

Many UNIX commands, but certainly not all, take the following form:

$ command -options filenames

Although the shell does not interpret the arguments of the command, the shell does make some

interpretation of the input line before passing the arguments to the command. Special characters,

when you enter them on a command line, cause the shell to redirect input and output, start a

different command, search the directories for filename patterns, substitute variable data, and

substitute the output of other commands.

Redirection of Input and Output

When the shell sees the input (<) or output (>) redirection characters, the argument following

the redirection symbol is sent to the subshell that controls the execution of the command. When

the command opens the input or output file that has been redirected, the input or output is

redirected to the file.

$ ls -l >dirfile

In this example, the only argument passed on to ls is the option -l. The filename dirfile is sent to

the subshell that controls the execution of ls. You can find more detail on input and output

redirection in Chapter 4, "Listing Files."

Entering Multiple Commands on One Line

Ordinarily, the shell interprets the first word of command input as the command name and the

rest of the input as arguments to that command. Three shell special characters—the semicolon

(;), the ampersand (&), and the vertical bar (|) or pipe—direct the shell to interpret the word

following the symbol as a new command, with the rest of the input as arguments to the new

command. For example, the command line

$ who -H; df -v; ps -e

is the equivalent of

$ who -H

$ df -v

$ ps -e

In the second case, however, the results of each command appear between the command input

lines. When you use the semicolon to separate commands on a line, the commands are executed

in sequence. The shell waits until one command is complete before executing the next.

If you separate commands on a line using the ampersand (&), the shell does not wait until one

command is run before the second is started. If the ampersand is the last character on the input

line, the last command is executed as a background job. To run the preceding series of

commands concurrently, you enter the following:

$ who -H & df -v & ps -e

Whereas the semicolon serves merely as a command separator, the pipe symbol serves a

different purpose. When the shell sees the pipe symbol, it takes the next word as a new

command and redirects the standard output of the prior command to the standard input of the

new command. For example, the command line

$ who | sort

displays an alphabetized list of all logged-in users. The command line

$ who | sort | lp

prints a hard copy of the alphabetized list of all logged-in users. You can find more information

on pipelines in Chapter 4, "Listing Files."

TIP: When you're using pipelines, sometimes the order of the commands does not

make a difference in the output, but it might make a difference in how efficiently the pipeline

executes. The two commands

sort /etc/inittab | grep bin/sh

grep bin/sh /etc/inittab | sort

accomplish the same thing, but the second pipeline operates more efficiently because it reduces

the amount of data passed to sort.

Entering Commands Too Long for One Line

Sometimes command lines get quite lengthy. On some terminals, when you reach the edge of

the display screen, the input autowraps to the next line, but depending on terminal settings,

some do not. It would be nice if you could type part of a command on one line and enter the

remainder of the command on a second line. You can accomplish by escaping the newline

character.

Remember that the shell sees a line of input as a string of characters terminated with a newline

character. But the newline character is also considered to be a white space character. If you end

a line with a backslash (\), the next character, which is the newline character, is treated literally,

meaning that the shell does not interpret the newline character as the end of the line of input. For

example,

$ echo Now is the time for all good men \_

to come to the aid of the party.

Now is the time for all good men to come to the aid of the party.

Filename Substitutions on the Command Line

Although the command separator, the pipe symbol, and the redirection symbols change the

operational effects of a command line, they did not affect the arguments that were passed to the

command. The substitution characters, on the other hand, cause a substitution to take place in

the stream of arguments passed to a command. The most common substitution is filename

substitution. When the shell's command-line interpreter sees one of the metacharacters—the

asterisk (*), the question mark (?), or square brackets ([,])—the shell searches the directories for

filenames that match a pattern indicated by the metacharacter.

The asterisk special character causes the shell to search the directory for filenames that match

any pattern. The command

$ ls f*

file1

file1a

form

creates a listing of all filenames beginning with the letter f. The important point here is that the

shell, not the ls command, did the directory search. In the following example, the ls command

sees three arguments, and the preceding command line is the equivalent of

$ ls file1 file1a form

file1

file1a

form

Tải ngay đi em, còn do dự, trời tối mất!
UNIX UNLEASHED PHẦN 2 doc | Siêu Thị PDF