convention, a shell is a user program that is ASCII based, that allows the user to specify operations in a
certain sequence.
There are four important concepts in a UNIX shell:
·
The user interacts with the system using a shell.
·
A sequence of operations can be scripted, or automatic, by placing the operations in a script file.
·
A shell is a full featured programming language, with variables, conditional statements, and the ability
to execute other programs. It can be, and is, used to prototype new programs.
·
A shell allows you to easily create a new program that is not a "second-class citizen," but instead is a
program with all of the privileges of any other UNIX program.
The last two points are important. DOS does not have a shell that has as many features as the Bourne
shell. Also, it is impossible to write a DOS script that emulates or replaces existing commands.
Let me give an example. Certain DOS programs understand the meta-character "*." That is, the
"RENAME" command can be told
RENAME *.OLD *.NEW
Files "A.OLD" and "B.OLD" will be renamed "A.NEW" and "B.NEW." The DOS commands "COPY" and
"MOVE" also understand the character "*." The "TYPE" and "MORE" commands, however, do not. If you
wanted to create a new command, it too, would not understand that an asterisk is used to match filenames.
You see, each DOS program is given the burden of understanding filename expansion. Consequently, many
programs do not.
UNIX is a different story. The shell is given the burden of expanding filenames. The program that sees the
filenames is unaware of the original pattern. This means all programs act consistently, as filename expansion
can be used with any command. It also means a shell script can easily replace a C program, as far as the user
is concerned. If you don't like the name of a UNIX utility, it is easy to create a new utility to replace the
current program. If you wanted to create a program called "DIR" you could simply create a file containing
#!/bin/sh
ls $*
The shell does the hard part.
The other difference between the DOS batch file and the UNIX shell is the richness of the shell language. It is
possible to do software development using the shell as the top level of the program. Not only is it possible, but
it is encouraged. The UNIX philosophy of program development is to start with a shell script. Get the
functionality you want. If the end results has all of the functionality, and is fast enough, then you are done. If
it isn't fast enough, consider replacing part (or all) of the script with a program written in a different language
(e.g. C, Perl). Just because a UNIX program is a shell script does not mean it isn't a "real" program.
Verifying which shell you are running
Because there are many shells available, it is important to learn to distinguish between the different shells.
Bourne Shell Tutorial
http://www.grymoire.com/Unix/Sh.html
4 of 66
11/21/2011 12:03 PM
Typing commands for one shell when you are using another is bound to cause confusion. I know from
personal experience. This was aggravated by the fact that many books I used to learn UNIX never mentioned
that other shells existed. Therefore, the first step is to make sure you are using the proper shell.
You can execute the following command to determine your default shell (The command you type is in
boldface):
% echo $SHELL
/bin/csh
While this identifies your default shell, it does not accurately identify the shell you are currently using. I will
give you a better way to find out later. Because this column discusses the Bourne shell, any commands
discussed here will only work right if you are using the Bourne shell. You have two choices: place these
commands in a Bourne shell script. That is, create a file, make the first line read
#!/bin/sh
Make the second line, and those following, contain the commands you want to test. Then make it executable
by typing
chmod +x filename
Once you do this, you can test the script by typing
./filename
The second method is to create a new window (if you desire). Then type
sh
You may see a change in the characters the shell gives you as a prompt, like the example below:
% /bin/sh
$
The Bourne shell will execute each line you type, until an end of file is found. To put it another way, when
you type Control-D, the Bourne shell will terminate, and return you to the shell you were previously using.
This is the same action the shell takes when a script file is executed, and the end of the script file is reached.
Shell basics
The basic actions of the shell are simple. It reads a line. This is either from a file, a script, or from a user. First,
meta-characters are "handled." Second, the name of the executable is found. Third, the arguments are passed
to the program. Fourth, the file redirection is setup. Lastly, the program is executed.
Meta-characters and Filename expansion
As the shell reads each line, it "handles" any special characters. This includes variable evaluation (variables
start with a "$)," and filename expansion. Expansion of filenames occurs when the characters "*," "?," or "["
occur in a word. A question mark matches a single character. An asterisk matches any number of characters,
Bourne Shell Tutorial
http://www.grymoire.com/Unix/Sh.html
5 of 66
11/21/2011 12:03 PM
including none. Square brackets are used to specify a range or particular combination of characters. Inside
square brackets, a hyphen is used to specify a range or characters. Also, if the first character inside the square
brackets is an exclamation point, the complement of the range is used. Let me give some examples:
+-------------------------------------------------------------------------------+
|
Table 1
|
|
Examples of filename expansion
|
+-------------------------------------------------------------------------------+
|Pattern
Matches
|
|*
Every file in the current directory
|
|?
Files consisting of one character
|
|??
Files consisting of two characters
|
|??*
Files consisting of two or more characters
|
|[abcdefg]
Files consisting of a single letter from a to g.
|
|[gfedcba]
Same as above
|
|[a-g]
Same as above
|
|[a-cd-g]
Same as above
|
|[a-zA-Z0-9]
Files that consist of a single letter or number
|
|[!a-zA-Z0-9]
Files that consist of a single character not a letter or number |
|[a-zA-Z]*
Files that start with a letter
|
|?[a-zA-Z]*
Files whose second character matches a letter.
|
|*[0-9]
Files that end with a number
|
|?[0-9]
Two character filename that end with a number
|
|*.[0-9]
Files that end with a dot and a number
|
+-------------------------------------------------------------------------------+
As you can see, the dot is not a special character. Filenames may or may not have a dot. UNIX Programers
use the dot to standardize on the type of source code of each file, but that is just a convention. There is
another convention, which concerns the shell:
Files whose name starts with a dot are not normally listed.
Again, it is a convention, but ls, find and the various shells follow this convention. This allows some files to
be "secret," or perhaps invisible, by default. You must explicitly ask for these files, by including the dot as
part of the filename. The pattern ".*" matches all hidden files. Remember that two hidden files are always in
every directory, ".," which indicate the present directory, and "..," which indicates the directory above the
current directory. If you want to match all hidden files except these two directories, there is no easy way to
specify a pattern that will always match all files except the two directories. I use
.??
or
.[a-zA-Z]*
As I said, this does not match all combinations, but works most of the time. Hackers (or crackers, if you
prefer) break into computers and often use strange filenames, like ". " or ".. " to hide their traces. You may
not have noticed, but there was a space in these filenames. Refering to files with spaces in the names require
quoting, which I will cover later. Personally, all of my hidden files are matched by ".[a-z]*" and all of my
hidden directories are matched by ".[A-Z]*." This works because I made up my own convention, and always
follow it.
The slash is also special, as it is used to indicate a directory path. Filename expansion does not expand to
match a slash, because a slash can never be part of the filename. Also, the same rules for filename expansion
of hidden files applies if the pattern follows a slash. If you want to match hidden files in a subdirectory, you
must specify the explicit pattern. Table 2 lists some examples.
Bourne Shell Tutorial
http://www.grymoire.com/Unix/Sh.html
6 of 66
11/21/2011 12:03 PM
Dostları ilə paylaş: |