JETZT ONLINE BESTELLEN
Second Edition April 2002
ISBN 978-0-596-00195-7
432 Seiten
EUR29.00
Weitere Informationen zu diesem Buch
Inhaltsverzeichnis | Kolophon |
Inhaltsverzeichnis
- Chapter 1: Korn Shell Basics
- InhaltsvorschauYou've used your computer for simple tasks, such as invoking your favorite application programs, reading your electronic mail, and perhaps examining and printing files. You know that your machine runs the Unix operating system, or maybe you know it under some other name, like Solaris, HP-UX, AIX, or SunOS. (Or you may be using a system such as GNU/Linux or one of the 4.4-BSD-derived systems that is not based on the original Unix source code.) But apart from that, you may not have given too much thought to what goes on inside the machine when you type in a command and hit ENTER.It is true that several layers of events take place whenever you enter a command, but we're going to consider only the top layer, known as the shell. Generally speaking, a shell is any user interface to the Unix operating system, i.e., any program that takes input from the user, translates it into instructions that the operating system can understand, and conveys the operating system's output back to the user.There are various types of user interface. The Korn shell belongs to the most common category, known as character-based user interfaces. These interfaces accept lines of textual commands that the user types; they usually produce text-based output. Other types of interface include the now-common graphical user interfaces (GUI), which add the ability to display arbitrary graphics (not just typewriter characters) and to accept input from mice and other pointing devices, touch-screen interfaces (such as those you see on some automatic teller machines), and so on.The shell's job, then, is to translate the user's command lines into operating system instructions. For example, consider this command line:
sort -n phonelist > phonelist.sorted
This means, "Sort lines in the file phonelist in numerical order, and put the result in the fileEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - What Is a Shell?
- InhaltsvorschauThe shell's job, then, is to translate the user's command lines into operating system instructions. For example, consider this command line:
sort -n phonelist > phonelist.sorted
This means, "Sort lines in the file phonelist in numerical order, and put the result in the file phonelist.sorted." Here's what the shell does with this command:-
Breaks up the line into the pieces
sort,-n,phonelist,>, andphonelist.sorted. These pieces are called words. -
Determines the purpose of the words:
sortis a command;-nandphonelistare arguments;>andphonelist.sorted, taken together, are I/O instructions. -
Sets up the I/O according to
> phonelist.sorted(output to the file phonelist.sorted) and some standard, implicit instructions. -
Finds the command sort in a file and runs it with the option -n (numerical order) and the argument phonelist (input filename).
Of course, each step really involves several substeps, and each substep includes a particular instruction to the underlying operating system.Remember that the shell itself is not Unix — just the user interface to it. This is illustrated in Figure 1-1. Unix is one of the first operating systems to make the user interface independent of the operating system.
Figure 1-1: The shell is a layer around the Unix operating systemEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Scope of This Book
- InhaltsvorschauIn this book, you will learn about the Korn shell, which is the most recent and powerful of the shells distributed with commercial Unix systems. There are two ways to use the Korn shell: as a user interface and as a programming environment.This chapter and the next cover interactive use. These two chapters should give you enough background to use the shell confidently and productively for most of your everyday tasks.After you have been using the shell for a while, you will undoubtedly find certain characteristics of your environment (the shell's "look and feel") that you would like to change and tasks that you would like to automate. Chapter 3 shows several ways of doing this.Chapter 3 also prepares you for shell programming, the bulk of which is covered in Chapter 4 through Chapter 6. You need not have any programming experience to understand these chapters and learn shell programming. Chapter 7 and Chapter 8 give more complete descriptions of the shell's I/O and process handling capabilities, and Chapter 9 discusses various techniques for finding and removing problems in your shell programs.You'll learn a lot about the Korn shell in this book; you'll also learn about Unix utilities and the way the Unix operating system works in general. It's possible to become a virtuoso shell programmer without any previous programming experience. At the same time, we've carefully avoided going down past a certain level of detail about Unix internals. We maintain that you shouldn't have to be an internals expert to use and program the shell effectively, and we won't dwell on the few shell features that are intended specifically for low-level systems programmers.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- History of Unix Shells
- InhaltsvorschauThe independence of the shell from the Unix operating system per se has led to the development of dozens of shells throughout Unix history, though only a few have achieved widespread use.The first major shell was the Bourne shell (named after its inventor, Stephen Bourne); it was included in the first widely popular version of Unix, Version 7, starting in 1979. The Bourne shell is known on the system as sh. Although Unix has gone through many, many changes, the Bourne shell is still popular and essentially unchanged. Several Unix utilities and administration features depend on it.The first widely used alternative shell was the C shell, or csh. It was written by Bill Joy at the University of California at Berkeley as part of the Berkeley Software Distribution (BSD) version of Unix that came out a couple of years after Version 7. It's included in essentially all recent Unix versions. (A popular variant is the so-called Twenex csh, tcsh.)The C shell gets its name from the resemblance of its commands to statements in the C programming language, which makes the shell easier for programmers on Unix systems to learn. It supports a number of operating system features (e.g., job control; see Chapter 8) that were once unique to BSD Unix but by now have migrated to just about all other modern versions. It also has a few important features (e.g., aliases; see Chapter 3) that make it easier to use in general.The Korn shell, or ksh, was invented by David Korn of AT&T Bell Laboratories in the mid-1980s. It is almost entirely upwardly compatible with the Bourne shell, which means that Bourne shell users can use it right away, and all system utilities that use the Bourne shell can use the Korn shell instead. In fact, some systems have the Korn shell installed as if it were the Bourne shell.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Getting the 1993 Korn Shell
- InhaltsvorschauThis book covers the 1993 version of the Korn shell. A large amount of what's covered is unique to that shell; a subset of what is unique applies only to the recent versions available directly from AT&T. In order to make best use of the book, you should be using the 1993 Korn shell. Use the following sequence of instructions to determine what shell you currently have and whether the 1993 Korn shell exists on your system, and to make the 1993 Korn shell be your login shell.
-
Determine which shell you are using. The
SHELLvariable denotes your login shell. Log in to your system and typeecho $SHELLat the prompt. You will see a response containingsh,csh, orksh; these denote the Bourne, C, and Korn shells, respectively. (There's also a good chance that you're using a third-party shell such as bash or tcsh.) If the response isksh, go to step 3. Otherwise, continue to step 2. -
See if some version of ksh exists on your system in a standard directory. Type
ksh. If that works (prints a$prompt), you have a version of the Korn shell; proceed to step 3. Otherwise, proceed to step 5. -
Check the version. Type
echo ${.sh.version}. If that prints a version, you're all set; skip the rest of these instructions. Otherwise, continue to step 4. -
You don't have the 1993 version of the Korn shell. To find out what version you do have, type the command
set -o emacs, then press CTRL-V. This will tell you if you have the 1988 version or the Public Domain Korn shell. In either case, continue to step 5. -
Type the command
/usr/dt/bin/dtksh. If this gives you a$prompt, you have the Desktop Korn Shell, which is based on an early version of ksh93. You may use this version; almost everything in this book will work. Go to step 7. -
You need to download an executable version of
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Interactive Shell Use
- InhaltsvorschauWhen you use the shell interactively, you engage in a login session that begins when you log in and ends when you
exitor press CTRL-D. During a login session, you type command lines into the shell; these are lines of text ending in ENTER that you type into your terminal or workstation. By default, the shell prompts you for each command with a dollar sign, though, as you will see in Chapter 3 the prompt can be changed.Shell command lines consist of one or more words, which are separated on a command line by spaces or TABs. The first word on the line is the command. The rest (if any) are arguments (also called parameters) to the command, which are names of things on which the command will act.For example, the command linelpr myfileconsists of the command lpr (print a file) and the single argument myfile. lpr treats myfile as the name of a file to print. Arguments are often names of files, but not necessarily: in the command linemail billr, the mail program treats billr as the name of the user to which a message will be sent.An option is a special type of argument that gives the command specific information on what it is supposed to do. Options usually consist of a dash followed by a letter; we say "usually" because this is a convention rather than a hard-and-fast rule. The commandlpr -h myfilecontains the option -h, which tells lpr not to print the "banner page" before it prints the file.Sometimes options take their own arguments. For example,lpr -P hp3si -h myfilehas two options and one argument. The first option is -P hp3si, which means "Send the output to the printer called hp3si." The second option and argument are as above.Almost all the built-in commands in ksh have both minimal and more extensive "online" help. If you give a command theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Files
- InhaltsvorschauAlthough arguments to commands aren't always files, files are the most important types of "things" on any Unix system. A file can contain any kind of information, and there are different types of files. Four types are by far the most important:
- Regular files
-
Also called text files; these contain readable characters. For example, this book was created from several regular files that contain the text of the book plus human-readable DocBook XML formatting instructions.
- Executable files
-
Also called programs; these are invoked as commands. Some can't be read by humans; others — the shell scripts that we'll examine in this book — are just special text files. The shell itself is a (not human-readable) executable file called ksh.
- Directories
-
Like folders that contain other files — possibly other directories (called subdirectories).
- Symbolic links
-
A kind of "shortcut" from one place in the system's directory hierarchy to another. We will see later in this chapter how symbolic links can affect interactive use of the Korn shell.
Let's review the most important concepts about directories. The fact that directories can contain other directories leads to a hierarchical structure, more popularly known as a tree, for all files on a Unix system. Figure 1-2 shows part of a typical directory tree; ovals are regular files and rectangles are directories.
Figure 1-2: A tree of directories and filesEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Input and Output
- InhaltsvorschauThe software field — really, any scientific field — tends to advance most quickly and impressively on those few occasions when someone (i.e., not a committee) comes up with an idea that is small in concept yet enormous in its implications. The standard input and output scheme of Unix has to be on the short list of such ideas, along with such classic innovations as the LISP language, the relational data model, and object-oriented programming.The Unix I/O scheme is based on two dazzlingly simple ideas. First, Unix file I/O takes the form of arbitrarily long sequences of characters (bytes). In contrast, file systems of older vintage have more complicated I/O schemes (e.g., "block," "record," "card image," etc.). Second, everything on the system that produces or accepts data is treated as a file; this includes hardware devices like disk drives and terminals. Older systems treated every device differently. Both of these ideas have made systems programmers' lives much more pleasant.By convention, each Unix program has a single way of accepting input called standard input, a single way of producing output called standard output, and a single way of producing error messages called standard error output, usually shortened to standard error. Of course, a program can have other input and output sources as well, as we will see in Chapter 7.Standard I/O was the first scheme of its kind that was designed specifically for interactive users, rather than the older batch style of use that usually involved decks of punch-cards. Since the Unix shell provides the user interface, it should come as no surprise that standard I/O was designed to fit in very neatly with the shell.All shells handle standard I/O in basically the same way. Each program that you invoke has all three standard I/O channels set to your terminal or workstation window, so that standard input is your keyboard, and standard output and error are your screen or window. For example, theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Background Jobs
- InhaltsvorschauPipes are actually a special case of a more general feature: doing more than one thing at a time. any other commercial operating systems don't have this capability, because of the rigid limits that they tend to impose upon users. Unix, on the other hand, was developed in a research lab and meant for internal use, so it does relatively little to impose limits on the resources available to users on a computer — as usual, leaning towards uncluttered simplicity rather than overcomplexity."Doing more than one thing at a time" means running more than one program at the same time. You do this when you invoke a pipeline; you can also do it by logging on to a Unix system as many times simultaneously as you wish. (If you try that on an IBM VM/CMS system, for example, you get an obnoxious "already logged in" message.)The shell also lets you run more than one command at a time during a single login session. Normally, when you type a command and hit ENTER, the shell lets the command have control of your terminal until it is done; you can't run further commands until the first one finishes. But if you want to run a command that does not require user input and you want to do other things while the command is running, put an ampersand (
&) after the command.This is called running the command in the background, and a command that runs in this way is called a background job; for contrast, a job run the normal way is called a foreground job. When you start a background job, you get your shell prompt back immediately, enabling you to enter other commands.The most obvious use for background jobs is programs that can take a long time to run, such as sort or gunzip on large files. For example, assume you just got an enormous compressed file loaded into your directory from magnetic tape. Today, the gzip utility is the de-facto file compression utility. gzip often achieves 50% to 90% compression of its input files. The compressed files have names of the formEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Special Characters and Quoting
- InhaltsvorschauThe characters
<,>,|, and&are four examples of special characters that have particular meanings to the shell. The wildcards we saw earlier in this chapter (*,?, and[...]) are also special characters.Table 1-6 gives indications of the meanings of all special characters within shell command lines only. Other characters have special meanings in specific situations, such as the regular expressions and string-handling operators we'll see in Chapter 3 and Chapter 4.Table 1-6: Special characters Character Meaning See chapter ~Home directory 1 `Command substitution (archaic) 4 #Comment 4 $Variable expression 3 &Background job 1 *String wildcard 1 (Start subshell 8 )End subshell 8 \Quote next character 1 |Pipe 1 [Start character-set wildcard 1 ]End character-set wildcard 1 {Start code block 7 }End code block 7 ;Shell command separator 3 'Strong quote 1 "Weak quote 1 <Input redirect 1 >Output redirect 1 /Pathname directory separator Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 2: Command-Line Editing
- InhaltsvorschauIt's always possible to make mistakes when you type at a computer keyboard, but perhaps even more so when you are using a Unix shell. Unix shell syntax is powerful, yet terse, full of odd characters, and not particularly mnemonic, making it possible to construct command lines that are as cryptic as they are complex. The Bourne and C shells exacerbate this situation by giving you extremely limited ways of editing your command lines.In particular, there is no way to recall a previous command line so that you can fix a mistake. For example, in Chapter 7 we'll see complex command lines like:
eval cat \$srcname \| ccom \| optimize \| as \> \$objname
If you are an experienced Bourne shell user, undoubtedly you know the frustration of having to retype lines like this. You can use the backspace key to edit, but once you hit ENTER, it's gone forever!The C shell provides a small improvement via its history mechanism, which provides a few very awkward ways of editing previous commands. But there are more than a few people who have wondered, "Why can't I edit my Unix command lines in the same way I can edit text with an editor?"This is exactly what the Korn shell allows you to do. It has editing modes that allow you to edit command lines with editing commands similar to those of the two most popular Unix editors, vi and Emacs. It also provides a much-extended analogue to the C shell history mechanism called hist (for "history") that, among other things, allows you to use your favorite editor directly for editing your command lines.In this chapter, we discuss features common to all of the Korn shell's command-history facilities; then we deal with each such facility in detail. If you use vi or Emacs, you may wish to read only the section on the emulation mode for the one you use. If you use neither vi or Emacs but are interested in learning one of the editing modes anyway, we suggest emacs-mode, because it is more of a natural extension of the minimal editing capability you get with the bare shell.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Enabling Command-Line Editing
- InhaltsvorschauThere are two ways of entering either editing mode. First, you can set your editing mode by using the environment variable
VISUAL. The Korn shell checks to see if this variable ends withviormacs. An excellent way to setVISUALis to put a line like the following in your .profile or environment file:VISUAL=$(whence emacs)
orVISUAL=$(whence vi)
As you will find out in Chapter 3 and Chapter 4, the whence built-in command takes the name of another command as its argument and writes the command's full pathname on the standard output; the form$(command)returns the standard output generated by command as a string value. Thus, the line above finds out the full pathname of your favorite editor and stores it in the environment variableVISUAL. The advantage of this code is that it is portable to other systems, which may have the executables for editors stored in different directories.The second way of selecting an editing mode is to set the option explicitly with the set -o command:set -o emacs
orset -o vi
vi users may wish to add:set -o viraw
along withset -o vi. This enables TAB completion in recent versions of ksh93. The additional overhead, particularly on single-user systems, is nominal and, in any case, is no worse than that of emacs-mode. (Starting with ksh93n, the viraw option is automatically enabled when you use vi-mode.)You will find that the vi and emacs editing modes are good at emulating the basic commands of these editors, but not advanced features; their main purpose is to let you transfer "finger habits" from your favorite editor to the shell.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - The History File
- InhaltsvorschauAll of the Korn shell's command history facilities depend on a file that stores commands as you type them in. This file is normally .sh_history in your home directory, but you can call it whatever you like by setting the environment variable
HISTFILE(see Chapter 3). When you run one of the Korn shell's editing modes, you are actually running a mini-editor on your history file.If you run more than one login session at a time (e.g., more than one xterm on an X Windows workstation), you may find it advantageous to maintain a separate history file for each login session. Put the following line in your .profile:HISTFILE=~/.hist.$(tty | sed 's;.*/;;')
This creates a history file whose name ends with the last component of your terminal's device name. For example, your window's terminal device name might be /dev/pts/42. The sed command strips everything through the last slash, leaving just the 42. The history file then becomes ~/.hist.42. You can remove the history file at logout, as explained in Chapter 4. Or you can leave the files around, and your history will be there the next time you start a window on that same terminal device. (Preserving history between sessions is the point of the history file, after all.)An attractive alternative is to use a single history file for all your windows. Each running instance of the Korn shell is smart enough to share its file with other running instances; from a second window, you can recall and edit the commands run in the first window.Another environment variable,HISTSIZE, can be used to determine the maximum number of commands accessible from the history file. The default is 128 (i.e., the 128 most recent commands), which should be more than adequate.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Emacs Editing Mode
- InhaltsvorschauIf you are an Emacs user, you will find it most useful to think of emacs editing mode as a simplified Emacs with a single, one-line window. All of the basic commands are available for cursor motion, cut and paste, and search.Emacs-mode uses control keys for the most basic editing functions. If you aren't familiar with Emacs, you can think of these as extensions of the rudimentary "erase" character (usually backspace or DEL) that Unix provides through its interface to users' terminals. In fact, emacs-mode figures out what your erase character is and uses that as its delete-backward key. For the sake of consistency, we'll assume your erase character is DEL from now on; if it is CTRL-H or something else, you will need to make a mental substitution. The most basic control-key commands are shown in Table 2-1.
Table 2-1: Basic emacs-mode commands Command Description CTRL-B Move backward one character (without deleting) CTRL-F Move forward one character DEL Delete one character backward CTRL-D Delete one character forward CTRL-Y Retrieve ("yank") last item deleted Remember that typing CTRL-D when your command line is empty may log you off!The basic finger habits of emacs-mode are easy to learn, but they do require that you assimilate a couple of concepts that are peculiar to the Emacs editor.The first of these is the use of CTRL-B and CTRL-F for backward and forward cursor motion. These keys have the advantage of being obvious mnemonics, but many people would rather use the arrow keys that are on just about every keyboard nowadays.Unfortunately, emacs-mode doesn't use the arrow keys, because the codes that they transmit to the computer aren't completely standardized; emacs-mode was designed to work on the widest variety of terminals possible without the heavy-duty customization that the full Emacs needs. Just about the only hardware requirements of emacs-mode are that the SPACE character overwrite the character on top of which it is typed, and that BACKSPACE moves to the left without overwriting the current character.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Vi Editing Mode
- InhaltsvorschauLike emacs-mode, vi-mode essentially creates a one-line editing window into the history file. Vi-mode is popular because vi is the most standard Unix editor. But the function for which vi was designed, writing C programs, has different editing requirements from those of command interpreters. As a result, although it is possible to do complex things in vi with relatively few keystrokes, the relatively simple things you need to do in the Korn shell sometimes take too many keystrokes.Like vi, vi-mode has two modes of its own: input and control mode. The former is for typing commands (as in normal Korn shell use); the latter is for moving around the command line and the history file. When you are in input mode, you can type commands and hit ENTER to run them. In addition, you have minimal editing capabilities via control characters, which are summarized in Table 2-6.
Table 2-6: Editing commands in vi input mode Command Description DEL Delete previous character CTRL-W Erase previous word (i.e., erase until whitespace) CTRL-V "Quote" the next character ESC Enter control mode (see below) At least some of these editig commands — depending on which version of Unix you have — are the same as those provided by modern Unix systems in the terminal interface. Vi-mode uses your "erase" character as the "delete previous character" key; usually it is set to DEL or CTRL-H (BACKSPACE). CTRL-V causes the next character you type to appear in the command line as is; i.e., if it is an editing command (or an otherwise special character like CTRL-D), it is stripped of its special meaning.Under normal circumstances, you just stay in input mode. But if you want to go back and make changes to your command line, or if you want to recall previous commands, you need to go into control mode. To do this, hit ESC.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - The hist Command
- Inhaltsvorschauhist is a shell built-in command that provides a superset of the C shell history mechanism. You can use it to examine the most recent commands you entered, to edit one or more commands with your favorite "real" editor, and to run old commands with changes without having to type the entire command in again. We'll look at each of these uses.The -l option for hist lists previous commands. It takes arguments that refer to commands in the history file. Arguments can be numbers or alphanumeric strings; numbers refer to the commands in the history file, while strings refer to the most recent command beginning with the string. hist treats arguments in a rather complex way:
-
If you give two arguments, they serve as the first and last commands to be shown.
-
If you specify one number argument, only the command with that number is shown.
-
With a single string argument, hist searches for the most recent command starting with that string and shows you everything from that command to the most recent command.
-
If you specify no arguments, you will see the last 16 commands you entered. Thus,
hist -lby itself is equivalent to the C shell history command, and indeed the Korn shell defines a built-in alias history as:alias history='hist -l'
As you will find out in Chapter 3, this means that you can typehistoryand the Korn shell will run the commandhist -l.
A few examples should make these options clearer. Let's say you logged in and entered these commands:ls -l more myfile vi myfile wc -l myfile pr myfile | lp -h
If you typehist -l(orhistory) with no arguments, you will see the above list with command numbers, as in:1 ls -l 2 more myfile 3 vi myfile 4 wc -l myfile 5 pr myfile | lp -h
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Finger Habits
- InhaltsvorschauTo paraphrase the old adage, old finger habits die hard. In fact, that is the primary reason for the choices of vi and Emacs for the Korn shell's editing modes. If you are an experienced user of one of these editors, by all means use the corresponding Korn shell editing mode. If you are a vi wizard, you probably know how to navigate between any two points on a line in three keystrokes or less.But if you're not, you should seriously consider adopting emacs-mode finger habits. Because it is based on control keys, just like the minimal editing support you may have already used with the Bourne or C shell, you will find emacs-mode easier to assimilate. Although the full Emacs is an extremely powerful editor, its command structure lends itself very well to small subsetting: there are several "mini-emacs" style editors floating around for Unix, MS-DOS, and other systems.The same cannot be said for vi, because its command structure is really meant for use in a full-screen editor. vi is quite powerful too, in its way, but its power becomes evident only when it is used for purposes similar to that for which it was designed: editing source code in C and LISP. Doing complicated things in vi takes relatively few keystrokes. But doing simple things takes more keystrokes in vi-mode than it does in emacs-mode. Unfortunately, the ability to do simple things with a minimal number of keystrokes is most desired in a command interpreter, especially nowadays when users are spending more time within applications and less time working with the shell.Both Korn shell editing modes have quite a few commands; you will undoubtedly develop finger habits that include just a few of them. If you use emacs-mode and you aren't familiar with the full Emacs, here is a subset that is easy to learn yet enables you to do just about anything:
-
For cursor motion around a command line, stick to CTRL-A and CTRL-E for beginning and end of line, and CTRL-F and CTRL-B for moving around.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Chapter 3: Customizing Your Environment
- InhaltsvorschauA common synonym for a Unix shell, or for the interface any computer program presents, is an environment. An environment is typically a collection of concepts that expresses the things a computer does in terms designed to be understandable and coherent, and a look and feel that is comfortable.For example, your desk at work is an environment. Concepts involved in desk work usually include memos, phone calls, letters, forms, etc. The tools on or in your desk that you use to deal with these things include paper, staples, envelopes, pens, a telephone, a calculator, etc. Every one of these has a set of characteristics that express how you use it; such characteristics range from location on your desk or in a drawer (for simple tools) to more sophisticated things like which numbers the memory buttons on your phone are set to. Taken together, these characteristics make up your desk's look and feel.You customize the look and feel of your desk environment by putting pens where you can most easily reach them, programming your phone buttons, etc. In general, the more customization you have done, the more tailored to your personal needs — and therefore the more productive — your environment is.Similarly, Unix shells present you with such concepts as files, directories, and standard input and output, while Unix itself gives you tools to work with these, such as file manipulation commands, text editors, and print queues. Your Unix environment's look and feel is determined by your keyboard and display, of course, but also by how you set up your directories, where you put each kind of file, and what names you give to files, directories, and commands. There are also more sophisticated ways of customizing your shell environment.The most basic means of customization that the Korn shell provides are these:
- Aliases
-
Synonyms for commands or command strings that you can define for convenience.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - The .profile File
- InhaltsvorschauIf you want to customize your environment, it is most important to know about a file called .profile in your home (login) directory. This is a file of shell commands, also called a shell script, that the Korn shell reads and runs whenever you log in to your system.If you use a large machine in an office or department, the odds are good that your system administrator has already set up a .profile file for you that contains a few standard things. This is one of the "hidden" files mentioned in Chapter 1; other common hidden files include .xinitrc (for the X Window System), .emacs (for the GNU Emacs editor), and .mailrc (for the Unix mail program).Your .profile, together with the environment file that we discuss towards the end of this chapter, will be the source of practically all of the customizations we discuss here as well as in subsequent chapters. Therefore, it is very important for you to become comfortable with a text editor like vi or Emacs so that you can try whatever customization techniques strike your fancy.Bear in mind, however, that if you add commands to your .profile, they will not take effect until you log out and log back in again, or type the command
login. Of course, you need not immediately add customization commands to your .profile — you can always just test them by typing them in yourself. (Be sure you test your changes though: it is possible to set things up in your .profile such that you can't log back in! Test your changes before logging out, by logging in again, perhaps from a new window or virtual console.)If you already have a .profile, it's likely to contain lines similar to some of these:PATH=/sbin:/usr/sbin:/usr/bin:/etc:/usr/ucb:/local/bin: stty stop ^S intr ^C erase ^? EDITOR=/usr/local/bin/emacs SHELL=/bin/ksh export EDITOR
These commands set up a basic environment for you, so you probably shouldn't change them until you learn about what they do — which you will by the end of this chapter. When you edit yourEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Aliases
- InhaltsvorschauPerhaps the easiest and most popular type of customization is the alias, which is a synonym for a command or command string. This is one of several Korn shell features that were appropriated from the C shell. You define an alias by entering (or adding to your .profile) a line with the following form:
alias new=original
(Notice that there are no spaces on either side of the equal sign (=); this is required syntax.) The alias command defines new to be an alias for original; whenever you typenew, the Korn shell substitutesoriginalinternally. (You cannot use any of the shell's special characters, such as*,$,=, and so on, in alias names.)There are a few basic ways to use an alias. The first, and simplest, is as a more mnemonic name for an existing command. Many commonly used Unix commands have names that are poor mnemonics and therefore are excellent candidates for aliasing; the classic example is:alias search=grep
grep, the Unix file-searching utility, derives its name from the command "g/re/p" in the original ed text editor, which does essentially the same thing as grep. (The regular expression matching code was carved out of ed to make a separate program.) This acronym may mean something to a computer scientist but probably not to the office administrator who has to findFredin a list of phone numbers. If you have to findFred, and you have the word search defined as an alias for grep, you can type:search Fred phonelist
Another popular alias eschews exit in favor of a more widely used command for ending a login session:alias logout=exit
If you are a C shell user, you may be used to having a .logout file of commands that the shell executes just before you log out. The Korn shell doesn't have this feature as such, but you can mimic it quite easily using an alias:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Options
- InhaltsvorschauWhile aliases let you create convenient names for commands, they don't really let you change the shell's behavior. Options are one way of doing this. A shell option is a setting that is either "on" or "off." While several options relate to arcane shell features that are of interest only to programmers, those that we cover here are of interest to all users.The basic commands that relate to options are
set -ooptionnames andset +ooptionnames, where optionnames is a list of option names separated by whitespace. The use of plus (+) and minus (-) signs is counterintuitive: the-turns the named option on, while the+turns it off. The reason for this incongruity is that the dash (-) is the conventional Unix way of specifying options to a command, while the use of+is an afterthought.Most options also have one-letter abbreviations that can be used in lieu of theset -ocommand; for example,set -o noglobcan be abbreviatedset -f. These abbreviations are carry-overs from the Bourne shell. Like several other "extra" Korn shell features, they exist to ensure upward compatibility; otherwise, their use is not encouraged.Table 3-1 lists the options that are useful to general Unix users. All of them are off by default except as noted.Table 3-1: Basic shell options Option Description bgnice Run background jobs at lower priority (on by default).emacs Enter emacs editing mode.ignoreeof Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Shell Variables
- InhaltsvorschauThere are several characteristics of your environment that you may want to customize but that cannot be expressed as an on/off choice. Characteristics of this type are specified in shell variables. Shell variables can specify everything from your prompt string to how often the shell checks for new mail.Like an alias, a shell variable is a name that has a value associated with it. The Korn shell keeps track of several built-in shell variables; shell programmers can add their own. By convention, built-in variables have names in all capital letters. The syntax for defining variables is somewhat similar to the syntax for aliases:
varname=valueThere must be no space on either side of the equal sign, and if the value is more than one word, it must be surrounded by quotes. To use the value of a variable in a command, precede its name by a dollar sign ($).You can delete a variable with the commandunsetvarname. Normally, this isn't useful, since all variables that don't exist are assumed to be null, i.e., equal to the empty string"". But if you use the option nounset (see Table 3-1), which causes the shell to indicate an error when it encounters an undefined variable, you may be interested in unset.The easiest way to check a variable's value is to use the print built-in command. All print does is print its arguments, but not until the shell has evaluated them. This includes — among other things that will be discussed later — taking the values of variables and expanding filename wildcards. So, if the variable fred has the valuebob, typing the following causes the shell to simply printbob:print "$fred"
If the variable is undefined, the shell prints a blank line. A more verbose way to do this is:print "The value of \$varname is \"$varname\"."
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Customization and Subprocesses
- InhaltsvorschauSome of the variables discussed above are used by commands you may run — as opposed to the shell itself — so that they can determine certain aspects of your environment. The majority, however, are not even known outside the shell.This dichotomy begs an important question: which shell "things" are known outside the shell, and which are only internal? This question is at the heart of many misunderstandings about the shell and shell programming. Before we answer, we'll ask it again in a more precise way: which shell "things" are known to subprocesses? Remember that whenever you enter a command, you are telling the shell to run that command in a subprocess; furthermore, some complex programs may start their own subprocesses.The answer is actually fairly simple. Subprocesses inherit only environment variables. They are available automatically, without the subprocess having to take any explicit action. All the other "things" — shell options, aliases, and functions — must be made explicitly available. The environment file is how you do this. Furthermore, only interactive shells process the environment file. The next two sections describe environment variables and the environment file, respectively.By default, only one kind of thing is known to all kinds of subprocesses: a special class of shell variables called environment variables. Some of the built-in variables we have seen are actually environment variables:
HISTFILE,HOME,LOGNAME,PATH,PWD,OLDPWD,SHELL, andTERM.It should be clear why these and other variables need to be known by subprocesses. We have already seen the most obvious example: text editors like vi and Emacs need to know what kind of terminal you are using;TERMis their way of determining this. As another example, most Unix mail programs allow you to edit a message with your favorite text editor. How doesEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Customization Hints
- InhaltsvorschauYou should feel free to try any of the techniques presented in this chapter. The best strategy is to test something out by typing it into the shell during your login session; if you decide you want to make it a permanent part of your environment, add it to your .profile.A nice, painless way to add to your .profile without going into a text editor makes use of the print command and one of the Korn shell's editing modes. If you type a customization command in and later decide to add it to your .profile, you can recall it via CTRL-P or CTRL-R (in emacs-mode) or
j,-, or/(vi-mode). Let's say the line is:PS1="($LOGNAME !)->"
After you recall it, edit it so that it is preceded by a print command, surrounded by single quotes, and followed by an I/O redirector that (as you will see in Chapter 7) appends the output to ~/.profile:print 'PS1="($LOGNAME !)->"' >> ~/.profile
Remember that the single quotes are important because they prevent the shell from trying to interpret things like dollar signs, double quotes, and exclamation points.You should also feel free to snoop around other peoples' .profile files for customization ideas. A quick way to examine everyone's .profile is as follows: let's assume that all login directories are under /home. Then you can type:cat /home/*/.profile > ~/other_profiles
and examine other people's .profile files with a text editor at your leisure (assuming you have read permission on them). If other users have environment files, the file you just created will show what they are, and you can examine them as well.Finally, be sure that no one else but you has write permission on your .profile and environment files.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 4: Basic Shell Programming
- InhaltsvorschauIf you have become familiar with the customization techniques we presented in the previous chapter, you have probably run into various modifications to your environment that you want to make but can't — yet. Shell programming makes these possible.The Korn shell has some of the most advanced programming capabilities of any command interpreter of its type. Although its syntax is nowhere near as elegant or consistent as that of most conventional programming languages, its power and flexibility are comparable. In fact, the Korn shell can be used as a complete environment for writing software prototypes.Some aspects of Korn shell programming are really extensions of the customization techniques we have already seen, while others resemble traditional programming language features. We have structured this chapter so that if you aren't a programmer, you can read this chapter and do quite a bit more than you could with the information in the previous chapter. Experience with a conventional programming language like Pascal or C is helpful (though not strictly necessary) for subsequent chapters. Throughout the rest of the book, we will encounter occasional programming problems, called tasks, whose solutions make use of the concepts we cover.A script, or file that contains shell commands, is a shell program. Your .profile and environment files, discussed in Chapter 3, are shell scripts.You can create a script using the text editor of your choice. Once you have created one, there are a number of ways to run it. One, which we have already covered, is to type
.scriptname (i.e., the command is a dot). This causes the commands in the script to be read and run as if you typed them in.Two more ways are to typekshscript orksh <script. These explicitly invoke the Korn shell on the script, requiring that you (and your users) be aware that they are scripts.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Shell Scripts and Functions
- InhaltsvorschauA script, or file that contains shell commands, is a shell program. Your .profile and environment files, discussed in Chapter 3, are shell scripts.You can create a script using the text editor of your choice. Once you have created one, there are a number of ways to run it. One, which we have already covered, is to type
.scriptname (i.e., the command is a dot). This causes the commands in the script to be read and run as if you typed them in.Two more ways are to typekshscript orksh <script. These explicitly invoke the Korn shell on the script, requiring that you (and your users) be aware that they are scripts.The final way to run a script is simply to type its name and hit ENTER, just as if you were invoking a built-in command. This, of course, is the most convenient way. This method makes the script look just like any other Unix command, and in fact several "regular" commands are implemented as shell scripts (i.e., not as programs originally written in C or some other language), including spell, man on some systems, and various commands for system administrators. The resulting lack of distinction between "user command files" and "built-in commands" is one factor in Unix's extensibility and, hence, its favored status among programmers.You can run a script by typing its name only if.(the current directory) is part of your command search path, i.e., is included in yourPATHvariable (as discussed in Chapter 3). If.isn't on your path, you must type./scriptname, which is really the same thing as typing the script's relative pathname (see Chapter 1).Before you can invoke the shell script by name, you must also give it "execute" permission. If you are familiar with the Unix filesystem, you know that files have three types of permissions (read, write, and execute) and that those permissions apply to three categories of user (the file's owner, a group of users, and everyone else). Normally, when you create a file with a text editor, the file is set up with read and write permission for you and read-only permission for everyone else.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Shell Variables
- InhaltsvorschauA major piece of the Korn shell's programming functionality relates to shell variables. We've already seen the basics of variables. To recap briefly: they are named places to store data, usually in the form of character strings, and their values can be obtained by preceding their names with dollar signs (
$). Certain variables, called environment variables, are conventionally named in all capital letters, and their values are made known (with the export statement) to subprocesses.This section presents the basics for shell variables. Discussion of certain advanced features is delayed until later in the chapter, after covering regular expressions.If you are a programmer, you already know that just about every major programming language uses variables in some way; in fact, an important way of characterizing differences between languages is comparing their facilities for variables.The chief difference between the Korn shell's variable schema and those of conventional languages is that the Korn shell's schema places heavy emphasis on character strings. (Thus it has more in common with a special-purpose language like SNOBOL than a general-purpose one like Pascal.) This is also true of the Bourne shell and the C shell, but the Korn shell goes beyond them by having additional mechanisms for handling integers and double-precision floating point numbers explicitly, as well as simple arrays.As we have already seen, you can define values for variables with statements of the form varname=value, e.g.:$ fred=bob $ print "$fred" bob
Some environment variables are predefined by the shell when you log in. There are other built-in variables that are vital to shell programming. We look at a few of them now and save the others for later.The most important special, built-in variables are called positional parametersEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Compound Variables
- Inhaltsvorschauksh93 introduces a new feature, called compound variables. They are similar in nature to a Pascal or Ada
recordor a Cstruct, and they allow you to group related items together under the same name. Here are some examples:now="May 20 2001 19:44:57" Assign current date to variable now now.hour=19 Set the hour now.minute=44 Set the minute ...
Note the use of the period in the variable's name. Here,nowis called the parent variable, and it must exist (i.e., have a value) before you can assign a value to an individual component (such ashourorminute). To access a compound variable, you must enclose the variable's name in curly braces. If you don't, the period ends the shell's scan for the variable's name:$ print ${now.hour} 19 $ print $now.hour May 20 2001 19:44:57.hourAssigning to individual elements of a compound variable is tedious. In particular the requirement that the parent variable exist previously leads to an awkward programming style:person="John Q. Public" person.firstname=John person.initial=Q. person.lastname=Public
Fortunately, you can use a compound assignment to do it all in one fell swoop:person=(firstname=John initial=Q. lastname=Public)
You can retrieve the value of either the entire variable, or a component, using print.$ print $person Simple print ( lastname=Public initial=Q. firstname=John ) $ print -r "$person" Print in full glory ( lastname=Public initial=Q. firstname=John ) $ print ${person.initial} Print just the middle initial Q.The second print command preserves the whitespace that the Korn shell provides when returning the value of a compound variable. TheEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Indirect Variable References (namerefs)
- InhaltsvorschauMost of the time, as we've seen so far, you manipulate variables directly, by name (
x=1, for example). The Korn shell allows you to manipulate variables indirectly, using something called a nameref. You create a nameref using typeset -n, or the more convenient predefined alias, nameref. Here is a simple example:$ name="bill" Set initial value $ nameref firstname=name Set up the nameref $ print $firstname Actually references variable name bill $ firstname="arnold" Now change the indirect reference $ print $name Shazzam! Original variable is changed arnoldTo find out the name of the real variable being referenced by the nameref, use${!variable}:$ print ${!firstname} nameAt first glance, this doesn't seem to be very useful. The power of namerefs comes into play when you pass a variable's name to a function, and you want that function to be able to update the value of that variable. The following example illustrates how it works:$ date Current day and time Wed May 23 17:49:44 IDT 2001 $ function getday { Define a function > typeset -n day=$1 Set up the nameref > day=$(date | awk '{ print $1 }') Actually change it > } $ today=now Set initial value $ getday today Run the function $ print $today Display new value WedThe default output of date(1) looks like this:$ date Wed Nov 14 11:52:38 IST 2001
The getday function uses awk to print the first field, which is the day of the week. The result of this operation, which is done inside command substitution (described later in this chapter), is assigned to the local variableEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - String Operators
- InhaltsvorschauThe curly-brace syntax allows for the shell's string operators. String operators allow you to manipulate values of variables in various useful ways without having to write full-blown programs or resort to external Unix utilities. You can do a lot with string-handling operators even if you haven't yet mastered the programming features we'll see in later chapters.In particular, string operators let you do the following:
-
Ensure that variables exist (i.e., are defined and have non-null values)
-
Set default values for variables
-
Catch errors that result from variables not being set
-
Remove portions of variables' values that match patterns
The basic idea behind the syntax of string operators is that special characters that denote operations are inserted between the variable's name and the right curly brace. Any argument that the operator may need is inserted to the operator's right.The first group of string-handling operators tests for the existence of variables and allows substitutions of default values under certain conditions. These are listed in Table 4-2.Table 4-2: Substitution operators Operator Substitution ${varname:-word}If varname exists and isn't null, return its value; otherwise return word.Purpose: Returning a default value if the variable is undefined.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Command Substitution
- InhaltsvorschauFrom the discussion so far, we've seen two ways of getting values into variables: by assignment statements and by the user supplying them as command-line arguments (positional parameters). There is another way: command substitution, which allows you to use the standard output of a command as if it were the value of a variable. You will soon see how powerful this feature is.The syntax of command substitution is:
$(Unix command)The command inside the parenthesis is run, and anything the command writes to standard output (and to standard error) is returned as the value of the expression. These constructs can be nested, i.e., the Unix command can contain command substitutions.Here are some simple examples:-
The value of
$(pwd)is the current directory (same as the environment variable$PWD). -
The value of
$(ls)is the names of all files in the current directory, separated by newlines. -
To find out detailed information about a command if you don't know where its file resides, type
ls -l $(whence -pcommand). The -p option forces whence to do a pathname lookup and not consider keywords, built-ins, etc. -
To get the contents of a file into a variable, you can use varname
=$(<filename).$(catfilename)will do the same thing, but the shell catches the former as a built-in shorthand and runs it more efficiently. -
If you want to edit (with Emacs) every chapter of your book on the Korn shell that has the phrase "command substitution," assuming that your chapter files all begin with ch, you could type:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Advanced Examples: pushd and popd
- InhaltsvorschauWe conclude this chapter with a couple of functions that you may find handy in your everyday Unix use. They solve the problem presented by Task 4-7.We start by implementing a significant subset of their capabilities and finish the implementation in Chapter 6. (For ease of development and explanation, our implementation ignores some things that a more bullet-proof version should handle. For example, spaces in filenames will cause things to break.)If you don't know what a stack is, think of a spring-loaded dish receptacle in a cafeteria. When you place dishes on the receptacle, the spring compresses so that the top stays at roughly the same level. The dish most recently placed on the stack is the first to be taken when someone wants food; thus, the stack is known as a "last-in, first-out" or LIFO structure. (Victims of a recession or company takeovers will also recognize this mechanism in the context of corporate layoff policies.) Putting something onto a stack is known in computer science parlance as pushing, and taking something off the top is called popping.A stack is very handy for remembering directories, as we will see; it can "hold your place" up to an arbitrary number of times. The
cd -form of the cd command does this, but only to one level. For example: if you are in firstdir and then you change to seconddir, you can typecd -to go back. But if you start out in firstdir, then change to seconddir, and then go to thirddir, you can usecd -only to go back to seconddir. If you typecd -again, you will be back inEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 5: Flow Control
- InhaltsvorschauIf you are a programmer, you may have read the last chapter — with its claim at the outset that the Korn shell has an advanced set of programming capabilities — and wondered where many features from conventional languages are. Perhaps the most glaringly obvious "hole" in our coverage thus far concerns flow control constructs like
if,for,while, and so on.Flow control gives a programmer the power to specify that only certain portions of a program run, or that certain portions run repeatedly, according to conditions such as the values of variables, whether or not commands execute properly, and others. We call this the ability to control the flow of a program's execution.Almost every shell script or function shown thus far has had no flow control — they have just been lists of commands to be run! Yet the Korn shell, like the C and Bourne shells, has all the flow control abilities you would expect and more; we examine them in this chapter. We'll use them to enhance the solutions to some of the programming tasks we saw in the last chapter and to solve tasks that we introduce here.Although we have attempted to explain flow control so that nonprogrammers can understand it, we also sympathize with programmers who dread having to slog through yet another tabula rasa explanation. For this reason, some of our discussions relate the Korn shell's flow-control mechanisms to those that programmers should know already. Therefore you will be in a better position to understand this chapter if you already have a basic knowledge of flow control concepts.The Korn shell supports the following flow control constructs:-
if/else -
Execute a list of statements if a certain condition is/is not true.
-
for -
Execute a list of statements a fixed number of times.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- if/else
- InhaltsvorschauThe simplest type of flow control construct is the conditional, embodied in the Korn shell's
ifstatement. You use a conditional when you want to choose whether or not to do something, or to choose among a small number of things to do, according to the truth or falsehood of conditions. Conditions test values of shell variables, characteristics of files, whether or not commands run successfully, and other factors. The shell has a large set of built-in tests that are relevant to the task of shell programming.Theifconstruct has the following syntax:if condition then statements [elif condition then statements ...] [else statements] fi
The simplest form (without theelifandelseparts, a.k.a. clauses) executes the statements only if the condition is true. If you add anelseclause, you get the ability to execute one set of statements if a condition is true or another set of statements if the condition is false. You can use as manyelif(a contraction of "else if") clauses as you wish; they introduce more conditions and thus more choices for which set of statements to execute. If you use one or moreelifs, you can think of theelseclause as the "if all else fails" part.Perhaps the only aspect of this syntax that differs from that of conventional languages like C and Pascal is that the "condition" is really a list of statements rather than the more usual Boolean (true or false) expression. How is the truth or falsehood of the condition determined? It has to do with a general Unix concept that we haven't covered yet: the exit status of commands.Every Unix command, whether it comes from source code in C, some other language, or a shell script/function, returns an integer code to its calling process — the shell in this case — when it finishes. This is called the exit status. 0 is usually the "OK" exit status, while anything else (1 to 255)Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - for
- InhaltsvorschauThe most obvious enhancement we could make to the previous script is the ability to report on multiple files instead of just one. Tests like -e and -d only take single arguments, so we need a way of calling the code once for each file given on the command line.The way to do this — indeed, the way to do many things with the Korn shell — is with a looping construct. The simplest and most widely applicable of the shell's looping constructs is the
forloop. We'll useforto enhance fileinfo soon.Theforloop allows you to repeat a section of code a fixed number of times. During each time through the code (known as an iteration), a special variable called a loop variable is set to a different value; this way each iteration can do something slightly different.Theforloop is somewhat, but not entirely, similar to its counterparts in conventional languages like C and Pascal. The chief difference is that the shell'sforloop doesn't let you specify a number of times to iterate or a range of values over which to iterate; instead, it only lets you give a fixed list of values. In other words, with the normalforloop, you can't do anything like this Pascal-type code, which executes statements 10 times:for x := 1 to 10 do begin statements ... end(You need the arithmeticforloop, which we'll see in Chapter 6, to do that.)However, theforloop is ideal for working with arguments on the command line and with sets of files (e.g., all files in a given directory). We'll look at an example of each of these. But first, here is the syntax for theforconstruct:for name [in list] do statements that can use $name ... done
The list is a list of names. (Ifinlist is omitted, the list defaults to"$@", i.e., the quoted list of command-line arguments, but we always supply theinlist for the sake of clarity.) In our solutions to the following task, we show two simple ways to specify lists.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - case
- InhaltsvorschauThe next flow control construct to cover is
case. While thecasestatement in Pascal and the similarswitchstatement in C can be used to test simple values like integers and characters, the Korn shell'scaseconstruct lets you test strings against patterns that can contain wildcard characters. Like its conventional language counterparts,caselets you express a series of if-then-else type statements in a concise way.The syntax ofcaseis as follows:case expression in pattern1 ) statements ;; pattern2 ) statements ;; ... esac
Any of the patterns can actually be several patterns separated by "OR bar" characters (|, which is the same as the pipe symbol, but in this context means "or"). If expression matches one of the patterns, its corresponding statements are executed. If there are several patterns separated by OR bars, the expression can match any of them in order for the associated statements to be run. The patterns are checked in order until a match is found; if none is found, nothing happens.This rather ungainly syntax should become clearer with an example. An obvious choice is to revisit our solution to Task 4-2, the front-end for the C compiler. Earlier in this chapter, we wrote some code that processed input files according to their suffixes (.c,.s, or.ofor C, assembly, or object code, respectively).We can improve upon this solution in two ways. First, we can useforto allow multiple files to be processed at one time; second, we can usecaseto streamline the code:for filename in "$@"; do case $filename in *.c ) objname=${filename%.c}.o ccom "$filename" "$objname" ;; *.s ) objname=${filename%.s}.o as "$filename" "$objname" ;; *.o ) ;; * ) print "error: $filename is not a source or object file." exit 1 ;; esac doneEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - select
- InhaltsvorschauAlmost all of the flow-control constructs we have seen so far are also available in the Bourne shell, and the C shell has equivalents with different syntax. Our next construct,
select, is unique to the Korn shell; moreover, it has no analogue in conventional programming languages.selectallows you to generate simple menus easily. It has concise syntax, but it does quite a lot of work. The syntax is:select name [in list] do statements that can use $name ... done
This is the same syntax as the regularforloop except for the keywordselect. And likefor, you can omitinlist, and it will default to"$@", i.e., the list of quoted command-line arguments.Here is whatselectdoes:-
Generates a menu of each item in list, formatted with numbers for each choice
-
Prompts the user for a number (with the value of
PS3) -
Stores the selected choice in the variable name and the selected number in the built-in variable
REPLY -
Executes the statements in the body
-
Repeats the process forever (but see below for how to exit)
Once again, an example should help make this process clearer. Assume you need to write the code for Task 5-4, but your life is not as simple. You don't have terminals hardwired to your computer; instead, your users communicate through a terminal server, or they log in remotely, via telnet or ssh. This means, among other things, that the tty number does not determine the type of terminal.Therefore, you have no choice but to prompt the user for his or her terminal type at login time. To do this, you can put the following code in /etc/profile (assume you have the same choice of terminal types):Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- while and until
- InhaltsvorschauThe remaining two flow control constructs the Korn shell provides are
whileanduntil. These are similar; both allow a section of code to be run repetitively while (or until) a certain condition holds true. They also resemble analogous constructs in Pascal (while/doandrepeat/until) and C (whileanddo/while).whileanduntilare actually most useful when combined with features we will see in the next chapter, such as arithmetic, input/output of variables, and command-line processing. Yet we can show a useful example even with the machinery we have covered so far.The syntax forwhileis:while condition do statements ... done
Foruntil, just substituteuntilforwhilein the above example. As withif, the condition is really a list of statements that are run; the exit status of the last one is used as the value of the condition. You can use a conditional with[[and]]here, just as you can withif.The only difference betweenwhileanduntilis the way the condition is handled. Inwhile, the loop executes as long as the condition is true; inuntil, it runs as long as the condition is false. So far, so familiar. However, theuntilcondition is checked at the top of the loop, not at the bottom as it is in analogous constructs in C and Pascal.The result is that you can convert anyuntilinto awhilesimply by negating the condition. The only place whereuntilmight be better is something like this:until command; do statements ... done
The meaning of this is essentially, "Do statements until command runs correctly." This is occasionally useful, such as when waiting for the occurrence of a particular event. However, we usewhilethroughout the rest of this book.Task 5-5 is a good candidate forwhileEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 6: Command-Line Options and Typed Variables
- InhaltsvorschauYou should have a healthy grasp of shell programming techniques now that you have gone through the previous chapters. What you have learned up to this point enables you to write many nontrivial, useful shell scripts and functions.Still, you may have noticed some remaining gaps in the knowledge you need to write shell code that behaves like the Unix commands you are used to. In particular, if you are an experienced Unix user, it might have occurred to you that none of the example scripts shown so far have the ability to handle options (preceded by a dash (
-)) on the command line. And if you program in a conventional language like C or Pascal, you will have noticed that the only type of data that we have seen in shell variables is character strings; we haven't seen how to do arithmetic, for example.These capabilities are certainly crucial to the shell's ability to function as a useful Unix programming language. In this chapter, we show how the Korn shell supports these and related features.We have already seen many examples of the positional parameters (variables called1,2,3, etc.) that the shell uses to store the command-line arguments to a shell script or function when it runs. We have also seen related variables like*and@(for the string(s) of all arguments) and#(for the number of arguments).Indeed, these variables hold all the information on the user's command line. But consider what happens when options are involved. Typical Unix commands have the form command [-options] args, meaning that there can be zero or more options. If a shell script processes the commandfred bob pete, then$1is ``bob'' and$2is ``pete''. But if the command isfred -o bob pete, then$1is -o,$2is ``bob'', and$3is ``pete''.You might think you could write code like this to handle it:if [[ $1 == -o ]]; then code that processes the -o option 1=$2 2=$3 fi normal processing of $1 and $2...Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Command-Line Options
- InhaltsvorschauWe have already seen many examples of the positional parameters (variables called
1,2,3, etc.) that the shell uses to store the command-line arguments to a shell script or function when it runs. We have also seen related variables like*and@(for the string(s) of all arguments) and#(for the number of arguments).Indeed, these variables hold all the information on the user's command line. But consider what happens when options are involved. Typical Unix commands have the form command [-options] args, meaning that there can be zero or more options. If a shell script processes the commandfred bob pete, then$1is ``bob'' and$2is ``pete''. But if the command isfred -o bob pete, then$1is -o,$2is ``bob'', and$3is ``pete''.You might think you could write code like this to handle it:if [[ $1 == -o ]]; then code that processes the -o option 1=$2 2=$3 fi normal processing of $1 and $2...But this code has several problems. First, assignments like1=$2are illegal because positional parameters are read-only. Even if they were legal, another problem is that this kind of code imposes limitations on how many arguments the script can handle — which is very unwise. Furthermore, if this command had several possible options, the code to handle all of them would get very messy very quickly.Luckily, the shell provides a way around this problem. The command shift performs the function of:1=$2 2=$3 ...
for every argument, regardless of how many there are. If you supply a numeric argument to shift, it shifts the arguments that many times over; for example,shift 3has this effect:1=$4 2=$5 ...
This leads immediately to some code that handles a single option (call it -o) and arbitrarily many arguments:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Numeric Variables and Arithmetic
- InhaltsvorschauThe expression
$(($OPTIND - 1))in the last example gives a clue as to how the shell can do integer arithmetic. As you might guess, the shell interprets words surrounded by$((and))as arithmetic expressions. Variables in arithmetic expressions do not need to be preceded by dollar signs. It is OK to supply the dollar sign, except when assigning a value to a variable.Arithmetic expressions are evaluated inside double quotes, like variables and command substitutions. We're finally in a position to state the definitive rule about quoting strings: When in doubt, enclose a string in single quotes, unless it contains any expression involving a dollar sign, in which case you should use double quotes.For example, the date(1) command on modern versions of Unix accepts arguments that tell it how to format its output. The argument+%jtells it to print the day of the year, i.e., the number of days since December 31st of the previous year.We can use+%jto print a little holiday anticipation message:print "Only $(( (365-$(date +%j)) / 7 )) weeks until the New Year!"
We'll show where this fits in the overall scheme of command-line processing in Chapter 7.The arithmetic expression feature is built in to the Korn shell's syntax, and it was available in the Bourne shell (most versions) only through the external command expr(1). Thus it is yet another example of a desirable feature provided by an external command (i.e., a syntactic kludge) being better integrated into the shell.[[...]]and getopts are also examples of this design trend.While expr and ksh88 were limited to integer arithmetic, ksh93 supports floating-point arithmetic. As we'll see shortly, you can do just about any calculation in the Korn shell that you could do in C or most other programming languages.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Arithmetic for
- InhaltsvorschauThe
forloop as described in Chapter 5 has been in Unix shells since the Version 7 Bourne Shell. As mentioned, you can't do Pascal or C-style looping for a fixed number of iterations with thatforloop. ksh93 introduced the arithmeticforloop to remedy this situation and to bring the shell closer to a traditional (some would say "real") programming language.The syntax resembles the shell's arithmetic facilities that we have just seen. It is almost identical to the syntax of the Cforloop, except for the extra set of parentheses:for ((init; condition; increment)) do statements ... done
Here, init represents something to be done once, at the start of the loop. The condition is tested, and as long as it's true, the shell executes statements. Before going back to the top of the loop to test the condition again, the shell executes increment.Any of init, condition, and increment may be omitted. A missing condition is treated as true; i.e., the loop body always executes. (The so-called "infinite loop" requires you to use some other method to leave the loop.) We'll use the arithmeticforloop for Task 6-2, which is our next, rather simple task.Here's the code; the explanation follows:sum=0 count=$# for ((i = 1; i <= count; i++)) do let "sum += $1" shift done print $sumThe first line initializes the variablesumto 0.sumaccumulates the sum of the arguments. The second line is mostly for readability;countindicates how many arguments there are. The third line starts the loop itself. The variableiis the loop control variable. The init clause sets it to 1, the condition clause tests it against the limitcount, and the increment clause adds 1 to it each time around the loop. One thing you'll notice right away is that inside theforloop header, there's no need for theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Arrays
- InhaltsvorschauSo far we have seen three types of variables: character strings, integers, and floating-point numbers. The fourth type of variable that the Korn shell supports is an array. As you may know, an array is like a list of things; you can refer to specific elements in an array with indices, so that
a[i]refers to the ith element of arraya. The Korn shell provides two kinds of arrays: indexed arrays, and associative arrays.The Korn shell provides an indexed array facility that, while useful, is much more limited than analogous features in conventional programming languages. In particular, indexed arrays can be only one-dimensional (i.e., no arrays of arrays), and they are limited to 4096 elements. Indices start at 0. This implies that the maximum index value is 4095. Furthermore, they may be any arithmetic expression: ksh automatically evaluates the expression to yield the actual index.There are three ways to assign values to elements of an array. The first is the most intuitive: you can use the standard shell variable assignment syntax with the array index in brackets ([]). For example:nicknames[2]=bob nicknames[3]=ed
These assignments put the valuesbobandedinto the elements of the arraynicknameswith indices 2 and 3, respectively. As with regular shell variables, values assigned to array elements are treated as character strings unless the assignment is preceded by let, or the array was declared to be numeric with one of the typeset options -i, -ui, -E, or -F. (Strictly speaking, the value assigned with let is still a string; it's just that with let, the shell evaluates the arithmetic expression being assigned to produce that string.)The second way to assign values to an array is with a variant of the set statement, which we saw in Chapter 3. The statement:set -A aname val1 val2 val3 ...creates the arrayEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - typeset
- InhaltsvorschauThe final Korn shell feature that relates to the kinds of values that variables can hold is the typeset command. If you are a programmer, you might guess that typeset is used to specify the type of a variable (integer, string, etc.); you'd be partially right.typeset is a rather ad hoc collection of things that you can do to variables that restrict the kinds of values they can take. Operations are specified by options to typeset; the basic syntax is:
typeset option varname[=value]
Here, option is an option letter preceded with a hyphen or plus sign. Options can be combined and multiple varnames can be used. If you leave out varname, the shell prints a list of variables for which the given option is turned on.The available options break down into two basic categories:-
String formatting operations, such as right- and left-justification, truncation, and letter case control
-
Type and attribute functions that are of primary interest to advanced programmers
typeset without options has an important meaning: if a typeset statement is used inside a function definition, the variables involved all become local to that function (in addition to any properties they may take on as a result of typeset options). The ability to define variables that are local to "subprogram" units (procedures, functions, subroutines, etc.) is necessary for writing large programs, because it helps keep subprograms independent of the main program and of each other.Local variable names are restricted to simple identifiers. When typeset is used with a compound variable name (i.e., one that contains periods), that variable is automatically global, even if the typeset statement occurs inside the body of a function.If you just want to declare a variable local to a function, useEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Chapter 7: Input/Output and Command-Line Processing
- InhaltsvorschauThe past few chapters have gone into detail about various shell programming techniques, mostly focused on the flow of data and control through shell programs. In this chapter, we'll switch the focus to two related topics. The first is the shell's mechanisms for doing file-oriented input and output. We present information that expands on what you already know about the shell's basic I/O redirectors.Second, we zoom in and talk about I/O at the line and word level. This is a fundamentally different topic, since it involves moving information between the domains of files/terminals and shell variables. print and command substitution are two ways of doing this that we've seen so far.Our discussion of line and word I/O then leads into a more detailed explanation of how the shell processes command lines. This information is necessary so that you can understand exactly how the shell deals with quotation, and so that you can appreciate the power of an advanced command called eval, which we cover at the end of the chapter.In Chapter 1 you learned about the shell's basic I/O redirectors,
<,>, and|. Although these are enough to get you through 95% of your Unix life, you should know that the Korn shell supports a total of 20 I/O redirectors. Table 7-1 lists them, including the three we've already seen. Although some of the rest are useful, others are mainly for systems programmers. We will wait until the next chapter to discuss the last three, which, along with>|and<<<, are not present in most Bourne shell versions.Table 7-1: I/O redirectors Redirector Function >fileDirect standard output to file Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - I/O Redirectors
- InhaltsvorschauIn Chapter 1 you learned about the shell's basic I/O redirectors,
<,>, and|. Although these are enough to get you through 95% of your Unix life, you should know that the Korn shell supports a total of 20 I/O redirectors. Table 7-1 lists them, including the three we've already seen. Although some of the rest are useful, others are mainly for systems programmers. We will wait until the next chapter to discuss the last three, which, along with>|and<<<, are not present in most Bourne shell versions.Table 7-1: I/O redirectors Redirector Function >fileDirect standard output to file <fileTake standard input from file cmd1 |cmd2Pipe; take standard output of cmd1 as standard input to cmd2>>fileDirect standard output to file; append to file if it already exists>|fileForce standard output to file even if noclobber is set<>fileOpen file for both reading and writing on standard input<<labelHere-document; see text <<-Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - String I/O
- InhaltsvorschauNow we'll zoom back in to the string I/O level and examine the print, printf, and read statements, which give the shell I/O capabilities that are more analogous to those of conventional programming languages.As we've seen countless times in this book, print simply prints its arguments to standard output. You should use it instead of the echo command, whose functionality differs from system to system. (The Korn shell's built-in version of echo emulates whatever the system's standard version of echo does.) Now we'll explore the print command in greater detail.
Section 7.2.1.1: print escape sequences
print accepts a number of options, as well as several escape sequences that start with a backslash. (You must use a double backslash if you don't surround the string that contains them with quotes; otherwise, the shell itself "steals" a backslash before passing the arguments to print.) These are similar to the escape sequences recognized by echo and the C language; they are listed in Table 7-2.These sequences exhibit fairly predictable behavior, except for\f. On some displays, it causes a screen clear, while on others it causes a line feed. It ejects the page on most printers.\vis somewhat obsolete; it usually causes a line feed.Table 7-2: print escape sequences Sequence Character printed \aALERT or CTRL-G \bBACKSPACE or CTRL-H \cOmit final newline and discontinue processing the string\EESCAPE or CTRL-[ Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Command-Line Processing
- InhaltsvorschauWe've seen how the shell processes input lines: it deals with single quotes (
' '), double quotes (" "), and backslashes (\), and it separates parameter, command and arithmetic expansions into words, according to delimiters in the variableIFS. This is a subset of the things the shell does when processing command lines.This section completes the discussion, in sometimes excruciating detail. We first examine two additional kinds of substitutions or expansions that the shell performs that may not be universally available. Then we present the full story of the order that the shell processes the command line. Covered next is the use of quoting, which prevents many or all of the substitution steps from occurring. Finally, we cover the eval command, which can be used for additional programmatic control of command line evaluations.Brace expansion is a feature borrowed from the Berkeley csh command interpreter and also available in the popular bash shell. Brace expansion is a way of saving typing when you have strings that are prefixes or suffixes of each other. For example, suppose you have the following files:$ ls cpp-args.c cpp-lex.c cpp-out.c cpp-parse.c
You could typevi cpp-{args,lex,parse}.cif you wished to edit three out of the four C files, and the shell would expand this intovi cpp-args.c cpp-lex.c cpp-parse.c. Furthermore, brace substitutions may be nested. For example:$ print cpp-{args,l{e,o}x,parse}.c cpp-args.c cpp-lex.c cpp-lox.c cpp-parse.cThis is a handy feature. We haven't covered it up until now because it's possible that your version of ksh may not have it. It is an optional feature that is enabled when ksh is compiled. However, it is enabled by default when ksh93 is compiled from source code.Process substitution allows you to open multiple process streams and feed them into a single program for processing. For example:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Chapter 8: Process Handling
- InhaltsvorschauThe Unix operating system built its reputation on a small number of concepts, all of which are simple yet powerful. We've seen most of them by now: standard input/output, pipes, text-filtering utilities, the tree-structured filesystem, and so on. Unix also gained notoriety as the first small-computer operating system to give each user control over more than one process. We call this capability user-controlled multitasking.If Unix is the only operating system that you're familiar with, you might be surprised to learn that several other major operating systems have been sadly lacking in this area. For example, Microsoft's MS-DOS, for IBM PC compatibles, has no multitasking at all, let alone user-controlled multitasking. IBM's own VM/CMS system for large mainframes handles multiple users but gives them only one process each. Compaq's OpenVMS has user-controlled multitasking, but it is limited and difficult to use. The latest generation of small-computer operating systems, such as Apple's Macintosh OS X (which is BSD-based) and Microsoft's Windows (Windows 95 and later), finally include user-controlled multitasking at the operating system level.But if you've gotten this far in this book, you probably don't think that multitasking is a big deal. You're probably used to the idea of running a process in the background by putting an ampersand (
&) at the end of the command line. You have also seen the idea of a shell subprocess in Chapter 4, when we showed how shell scripts run.In this chapter, we cover most of the Korn shell's features that relate to multitasking and process handling in general. We say "most" because some of these features are, like the file descriptors we saw in Chapter 7, of interest only to low-level systems programmers.We start out by looking at certain important primitives for identifying processes and for controlling them during login sessions and within shell scripts. Then we move out to a higher-level perspective, looking at ways to get processes to communicate with each other. The Korn shell's coroutine facility is the most sophisticated interprocess communication scheme that we'll examine; we also look in more detail at concepts we've already seen, like pipes and shell subprocesses.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Process IDs and Job Numbers
- InhaltsvorschauUnix gives all processes numbers, called process IDs, when they are created. You will notice that, when you run a command in the background by appending
&to it, the shell responds with a line that looks like this:$ fred & [1] 2349
In this example, 2349 is the process ID for the fred process. The[1]is a job number assigned by the shell (not the operating system). What's the difference? Job numbers refer to background processes that are currently running under your shell, while process IDs refer to all processes currently running on the entire system, for all users. The term job basically refers to a command line that was invoked from your login shell.If you start up additional background jobs while the first one is still running, the shell numbers them 2, 3, etc. For example:$ bob & [2] 2367 $ dave | george & [3] 2382
Clearly, 1, 2, and 3 are easier to remember than 2349, 2367, and 2382!The shell includes job numbers in messages it prints when a background job completes, like this:[1] + Done fred &
We'll explain what the plus sign means soon. If the job exits with nonzero status (see Chapter 5), the shell includes the exit status in parentheses:[1] + Done(1) fred &
The shell prints other types of messages when certain abnormal things happen to background jobs; we'll see these later in this chapter.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Job Control
- InhaltsvorschauWhy should you care about process IDs or job numbers? Actually, you could probably get along fine in your Unix life without ever referring to process IDs (unless you use a windowing workstation — as we'll see soon). Job numbers are more important, however: you can use them with the shell commands for job control.You already know the most obvious way to control a job: you can create one in the background with
&. Once a job is running in the background, you can let it run to completion, bring it into the foreground, or send it a message called a signal.The built-in command fg brings a background job into the foreground. Normally this means that the job has control of your terminal or window and therefore is able to accept your input. In other words, the job begins to act as if you typed its command without the&.If you have only one background job running, you can use fg without arguments, and the shell brings that job into the foreground. But if you have several jobs running in the background, the shell picks the one that you put into the background most recently. If you want a different job put into the foreground, you need to use the job's command name, preceded by a percent sign (%), or you can use its job number, also preceded by%, or its process ID without a percent sign. If you don't remember which jobs are running, you can use the jobs command to list them.A few examples should make this clearer. Let's say you created three background jobs as above. If you type jobs, you see this:[1] Running fred & [2] - Running bob & [3] + Running dave | george &
jobs has a few interesting options. Besides the job status,jobs -lalso lists process group IDs:[1] 2349 Running fred & [2] - 2367 Running bob & [3] + 2382 Running dave | george &
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Signals
- InhaltsvorschauWe said earlier that typing CTRL-Z to suspend a job is similar to typing CTRL-C to stop a job, except that you can resume the job later. They are actually similar in a deeper way: both are particular cases of the act of sending a signal to a process.A signal is a message that one process sends to another when some abnormal event takes place or when it wants the other process to do something. Most often, a process sends a signal to a subprocess it created. You're undoubtedly already comfortable with the idea that one process can communicate with another through an I/O pipeline; think of a signal as another way for processes to communicate with each other. (In fact, any textbook on operating systems will tell you that both are examples of the general concept of interprocess communication, or IPC.)Depending on the version of Unix, there are two or three dozen types of signals, including a few that can be used for whatever purpose a programmer wishes. Signals have numbers (from 1 to the number of signals the system supports) and names; we'll use the latter. You can get a list of all the signals on your system by typing
kill -l. Bear in mind, when you write shell code involving signals, that signal names are more portable to other versions of Unix than signal numbers.When you type CTRL-C, you tell the shell to send the INT (for "interrupt") signal to the current job; CTRL-Z sends TSTP (for "terminal stop"). You can also send the current job a QUIT signal by typing CTRL-\ (control-backslash); this is sort of like a "stronger" version of CTRL-C. You would normally use CTRL-\ when (and only when) CTRL-C doesn't work.As we'll see soon, there is also a "panic" signal called KILL that you can send to a process when even CTRL-\ doesn't work. But it isn't attached to any control key, which means that you can't use it to stop the currently running process. INT, TSTP, and QUIT are the only signals you can use with control keys (although some systems have additional control-key signals).Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - trap
- InhaltsvorschauWe've been discussing how signals affect the casual user; now let's talk a bit about how shell programmers can use them. We won't go into too much depth about this, because it's really the domain of systems programmers.We mentioned earlier that programs in general can be set up to "trap" specific signals and process them in their own way. The trap built-in command lets you do this from within a shell script. trap is most important for "bullet-proofing" large shell programs so that they react appropriately to abnormal events — just as programs in any language should guard against invalid input. It's also important for certain systems programming tasks, as we'll see in the next chapter.The syntax of trap is:
trap cmd sig1 sig2 ...That is, when any of sig1, sig2, etc., are received, run cmd, then resume execution. After cmd finishes, the script resumes execution just after the command that was interrupted.Of course, cmd can be a script or function. The sigs can be specified by name or by number. You can also invoke trap without arguments, in which case the shell prints a list of any traps that have been set, using symbolic names for the signals. If you usetrap -p, the shell prints the trap settings in a way that can be saved and reread later by a different invocation of the shell.The shell scans the text of cmd twice. The first time is while it is preparing to run the trap command; all the substitutions as outlined in Chapter 7 are performed before executing the trap command. The second time is when the shell actually executes the trap. For this reason, it is best to use single quotes around the cmd in the text of the shell program. When the shell executes the trap's command,$?is always the exit status of the last command run before the trap started. This is important for diagnostics.Here's a simple example that shows how trap works. Suppose we have a shell script calledEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Coroutines
- InhaltsvorschauWe've spent the last several pages on almost microscopic details of process behavior. Rather than continue our descent into the murky depths, we'll revert to a higher-level view of processes.Earlier in this chapter, we covered ways of controlling multiple simultaneous jobs within an interactive login session; now we consider multiple process control within shell programs. When two (or more) processes are explicitly programmed to run simultaneously and possibly communicate with each other, we call them coroutines.This is actually nothing new: a pipeline is an example of coroutines. The shell's pipeline construct encapsulates a fairly sophisticated set of rules about how processes interact with each other. If we take a closer look at these rules, we'll be better able to understand other ways of handling coroutines — most of which turn out to be simpler than pipelines.When you invoke a simple pipeline, say
ls | more, the shell invokes a series of Unix primitive operations, a.k.a. system calls. In effect, the shell tells Unix to do the following things; in case you're interested, we include in parentheses the actual system call used at each step:-
Create the pipe that will handle I/O between the processes (the pipe system call).
-
Create two subprocesses, which we'll call P1 and P2 (fork).
-
Set up I/O between the processes so that P1's standard output feeds into P2's standard input (dup, close).
-
Start /bin/ls in process P1 (exec).
-
Start /bin/more in process P2 (exec).
-
Wait for both processes to finish (wait).
You can probably imagine how the above steps change when the pipeline involves more than two processes.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Shell Subprocesses and Subshells
- InhaltsvorschauCoroutines clearly represent the most complex relationship between processes that the Korn shell defines. To conclude this chapter, we will look at a much simpler type of interprocess relationship: that of a shell subprocess with its parent shell. We saw in Chapter 3 that whenever you run a shell script, you actually invoke another copy of the shell that is a subprocess of the main, or parent, shell process. Now let's look at them in more detail.The most important things you need to know about shell subprocesses are what characteristics they get, or inherit, from their parents. These are as follows:
-
The current directory
-
Environment variables
-
Standard input, output, and error plus any other open file descriptors
-
Any characteristics defined in the environment file (see Chapter 3). Note that only interactive shells execute the environment file
-
Signals that are ignored
The first three characteristics are inherited by all subprocesses, while the last two are unique to shell subprocesses. Just as important are the things that a shell subprocess does not inherit from its parent:-
Shell variables, except environment variables and those defined in the environment file
-
Handling of signals that are not ignored
We covered some of this earlier (in Chapter 3), but these points are common sources of confusion, so they bear repeating.A special kind of shell subprocess is theEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Chapter 9: Debugging Shell Programs
- InhaltsvorschauWe hope that we have convinced you that the Korn shell can be used as a serious Unix programming environment. It certainly has plenty of features, control structures, etc. But another essential part of a programming environment is a set of powerful, integrated support tools. For example, there is a wide assortment of screen editors, compilers, debuggers, profilers, cross-referencers, etc., for languages like C, C++ and Java. If you program in one of these languages, you probably take such tools for granted, and you would undoubtedly cringe at the thought of having to develop code with, say, the ed editor and the adb machine-language debugger.But what about programming support tools for the Korn shell? Of course, you can use any editor you like, including vi and Emacs. And because the shell is an interpreted language, you don't need a compiler. But there are no other tools available. The most serious problem is the lack of a debugger.This chapter addresses that lack. The shell does have a few features that help in debugging shell scripts; we'll see these in the first part of the chapter. The Korn shell also has a couple of new features, not present in most Bourne shells, that make it possible to implement a full-blown debugging tool. We show these features; more importantly, we present kshdb, a Korn shell debugger that uses them. kshdb is basic yet quite usable, and its implementation serves as an extended example of various shell programming techniques from throughout this book.What sort of functionality do you need to debug a program? At the most empirical level, you need a way of determining what is causing your program to behave badly and where the problem is in the code. You usually start with an obvious what (such as an error message, inappropriate output, infinite loop, etc.), try to work backwards until you find a what that is closer to the actual problem (e.g., a variable with a bad value, a bad option to a command), and eventually arrive at the exactEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Basic Debugging Aids
- InhaltsvorschauWhat sort of functionality do you need to debug a program? At the most empirical level, you need a way of determining what is causing your program to behave badly and where the problem is in the code. You usually start with an obvious what (such as an error message, inappropriate output, infinite loop, etc.), try to work backwards until you find a what that is closer to the actual problem (e.g., a variable with a bad value, a bad option to a command), and eventually arrive at the exact where in your program. Then you can worry about how to fix it.Notice that these steps represent a process of starting with obvious information and ending up with often obscure facts gleaned through deduction and intuition. Debugging aids make it easier to deduce and intuit by providing relevant information easily or even automatically, preferably without modifying your code.The simplest debugging aid (for any language) is the output statement, print in the shell's case. Indeed, old-time programmers debugged their Fortran code by inserting
WRITEcards into their decks. You can debug by putting lots of print statements in your code (and removing them later), but you will have to spend lots of time narrowing down not only what exact information you want but also where you need to see it. You will also probably have to wade through lots and lots of output to find the information that you really want.Luckily, the shell has a few basic features that give you debugging functionality beyond that of print. The most basic of these are options to the set -o command (as covered in Chapter 3). These options can also be used on the command line when running a script, as Table 9-1 shows.The verbose option simply echoes (to standard error) whatever input the shell gets. It is useful for finding the exact point at which a script is bombing. For example, assume your script looks like this:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - A Korn Shell Debugger
- InhaltsvorschauCommercially available debuggers give you much more functionality than the shell's set options and fake signals. The most advanced have fabulous graphical user interfaces, incremental compilers, symbolic evaluators, and other such amenities. But just about all modern debuggers — even the more modest ones — have features that enable you to "peek" into a program while it's running, to examine it in detail and in terms of its source language. Specifically, most debuggers let you do these things:
-
Specify points at which the program stops execution and enters the debugger. These are called breakpoints.
-
Execute only a bit of the program at a time, usually measured in source code statements. This ability is often called stepping.
-
Examine and possibly change the state of the program (e.g., values of variables) in the middle of a run, i.e., when stopped at a breakpoint or after stepping.
-
Specify variables whose values should be printed when they are changed or accessed. These are often called watchpoints.
-
Do all of the above without having to change the source code.
Our debugger, called kshdb, has these features and a few more. Although it's a basic tool, without too many bells and whistles, it is not a toy. This book's web site,http://www.oreilly.com/catalog/korn2/, has a link for a downloadable copy of all the book's example programs, including kshdb. If you don't have access to the Internet, you can type or scan the code in. Either way, you can use kshdb to debug your own shell scripts, and you should feel free to enhance it. This is version 2.0 of the debugger. It includes some changes suggested to us by Steve Alston, and the watchpoints feature is brand new. We'll suggest some enhancements at the end of this chapter.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Chapter 10: Korn Shell Administration
- InhaltsvorschauSystem administrators use the shell as part of their job of setting up a system-wide environment for all users. In this chapter, we discuss the Korn shell's features that relate to this task from two perspectives: customization that is available to all users and system security. We assume that you already know the basics of Unix system administration.As a prelude to system-wide customization, we want to emphasize something about the Korn shell that doesn't apply to most other shells: you can install it as if it were the standard Bourne shell, i.e., as /bin/sh. Just save the real Bourne shell as another filename, such as /bin/bsh, in case anyone actually needs it for anything (which is doubtful), then rename (or link) your Korn shell as /bin/sh.Many installations have done this with absolutely no ill effects. Not only does this make the Korn shell your system's standard login shell, but it also makes most existing Bourne shell scripts run faster, and it has security advantages that we'll see later in this chapter.As we will see in Appendix A, the Korn shell is backward-compatible with the Bourne shell except that it doesn't support
^as a synonym for the pipe character|. Unless you have an ancient Unix system, or you have some very, very old shell scripts, you needn't worry about this.But if you want to be absolutely sure, simply search through all shell scripts in all directories in yourPATH. An easy way to do this is to use the file(1) command, which we saw in Chapter 5 and Chapter 9. file prints "executable shell script" when given the name of one. (The exact message varies from system to system; make sure that yours prints this message when given the name of a shell script. If not, just substitute the message your file command prints for "shell script" in the following example.) Here is a script that looks for^in shell scripts in every directory in yourPATH:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Installing the Korn Shell as the Standard Shell
- InhaltsvorschauAs a prelude to system-wide customization, we want to emphasize something about the Korn shell that doesn't apply to most other shells: you can install it as if it were the standard Bourne shell, i.e., as /bin/sh. Just save the real Bourne shell as another filename, such as /bin/bsh, in case anyone actually needs it for anything (which is doubtful), then rename (or link) your Korn shell as /bin/sh.Many installations have done this with absolutely no ill effects. Not only does this make the Korn shell your system's standard login shell, but it also makes most existing Bourne shell scripts run faster, and it has security advantages that we'll see later in this chapter.As we will see in Appendix A, the Korn shell is backward-compatible with the Bourne shell except that it doesn't support
^as a synonym for the pipe character|. Unless you have an ancient Unix system, or you have some very, very old shell scripts, you needn't worry about this.But if you want to be absolutely sure, simply search through all shell scripts in all directories in yourPATH. An easy way to do this is to use the file(1) command, which we saw in Chapter 5 and Chapter 9. file prints "executable shell script" when given the name of one. (The exact message varies from system to system; make sure that yours prints this message when given the name of a shell script. If not, just substitute the message your file command prints for "shell script" in the following example.) Here is a script that looks for^in shell scripts in every directory in yourPATH:dirs=$(print -- $PATH | sed -e 's/^:/.:/' -e 's/::/:.:/' -e s'/:$/:./' -e 's/:/ /g') for d in $dirs do print "checking $d:" cd "$d" scripts=$(file * | grep 'shell script' | cut -d: -f1) grep -l '\^' $scripts /dev/null done
The first statement of this script pulls$PATHapart into separate directories, including handling the several cases of empty separators which signify the current directory. TheEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Environment Customization
- InhaltsvorschauLike the Bourne shell, the Korn shell uses the file /etc/profile for system-wide customization. When a user logs in, the shell reads and runs /etc/profile before running the user's .profile.We don't cover all the possible commands you might want to put in /etc/profile. But the Korn shell has a few unique features that are particularly relevant to system-wide customization; we discuss them here.We'll start with two built-in commands that you can use in /etc/profile to tailor your users' environments and constrain their use of system resources. Users can also use these commands in their .profile, or at any other time, to override the default settings.umask, like the same command in most other shells, lets you specify the default permissions that files have when users create them. With ksh, it takes the same types of arguments that the chmod command does, i.e., absolute (octal numbers) or symbolic permission values.The umask contains the permissions that are turned off by default whenever a process creates a file, regardless of what permission the process specifies. Another way to think of this is as a bitwise borrow-free subtraction: actual permissions = requested permissions - the umask.We'll use octal notation to show how this works. As you should know, the digits in a permission number stand (left to right) for the permissions of the owner, the owner's group, and all other users, respectively. Each digit, in turn, consists of three bits, which specify read, write, and execute permissions from left to right. (If a file is a directory, the "execute" permission becomes "search" permission, i.e., permission to cd to it, and to traverse it as part of a pathname.)For example, the octal number 640 equals the binary number 110 100 000. If a file has this permission, then its owner can read and write it; users in the owner's group can only read it; everyone else has no permission on it. A file with permission 755 (111 101 101 in binary) gives its owner the right to read, write, and execute it and everyone else the right to read and execute (but not write).Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- Customizing the Editing Modes
- InhaltsvorschauAs we saw in Chapter 2, you have your choice of either emacs or vi editing modes when editing your command line. Besides the commands available in each mode, you can customize the behavior of the editing modes to suit your needs or environment.Appendix A discusses a number of third party shells based on the Bourne and Korn shell design. Those shells generally provide command-line editing, as well as the ability to customize the editor via a special built-in command, a special start-up file, or both.The Korn shell's approach is different. It is based on a paradigm where you program the behavior you want from the shell. This is accomplished via a fake trap, named KEYBD. If it exists, the trap set for KEYBD is evaluated when ksh processes normal command-line input characters. Within the code executed for the trap, two special variables contain the text of the command line and the text being entered that caused the trap. Additional special variables allow you to distinguish between emacs- and vi-modes and indicate the current position on the input line. These variables are listed in Table 10-2.
Table 10-2: Special editing variables Variable Meaning .sh.edcharThe character or escape sequence entered by the user that caused the KEYBD trap. The value of.sh.edcharat the end of the trap is then used to direct the actions of the built-in editor..sh.edcolThe position of the cursor on the current input line..sh.edmodeEqual to ESC in vi-mode, empty otherwise. (Use[[ -n ${.sh.edmode} ]]to test it.).sh.edtextEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - System Security Features
- InhaltsvorschauUnix security is a problem of legendary notoriety. Just about every aspect of a Unix system has some security issue associated with it, and it's usually the system administrator's job to worry about this issue.This is not a textbook on Unix system security. Be aware that this section merely touches the tip of the iceberg and that there are myriad other aspects to Unix system security besides how the shell is set up. See the end of the chapter for one book that we recommend.We first present a list of "tips" for writing shell scripts that have a better chance of avoiding security problems. Next we cover the restricted shell, which attempts to put a straitjacket around the user's environment. Then we present the idea of a "trojan horse," and why such things should be avoided. Finally we discuss the Korn shell's privileged mode, which is used with shell scripts that run as if the user were
root.Here are some tips for writing more secure shell scripts, courtesy of Professor Eugene (Gene) Spafford, the director of Purdue University's Center for Education and Research in Information Assurance and Security:- Don't put dot in PATH
-
This issue was described in Chapter 3. This opens the door wide for "trojan horses," described in the next section.
- Protect bin directories
-
Make sure that every directory in
$PATHis writable only by its owner and by no one else. The same applies to all the programs in the bin directories. - Design before you code
-
Spend some time thinking about what you want to do and how to do it; don't just type stuff in with a text editor and keep hacking until it seems to work. Include code to handle errors and failures gracefully.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Appendix A: Related Shells
- InhaltsvorschauThe fragmentation of the Unix marketplace has had its advantages and disadvantages. The advantages came mostly in the early days: lack of standardization and proliferation among technically savvy academics and professionals contributed to a healthy "free market" for Unix software, in which several programs of the same type (e.g., shells, text editors, system administration tools) would often compete for popularity. The best programs would usually become the most widespread, while inferior software tended to fade away.But often there was no single "best" program in a given category, so several would prevail. This led to the current situation, where multiplicity of similar software has led to confusion, lack of compatibility, and — most unfortunate of all — Unix's inability to capture as big a share of the market as other operating platforms. In particular, Unix has been relegated to its current position as a very popular operating system for servers, but it's a rarity on desktop machines.The "shell" category has probably suffered in this way more than any other type of software. As we said in the preface and Chapter 1, it is one of the strengths of Unix that the shell is replaceable, and thus a number of shells are currently available; the differences between them are often not all that great. We believe that the Korn shell is one of the best of the most widely used shells, but other shells certainly have their staunch adherents, so they aren't likely to fade into obscurity. In fact, it seems that shells, Bourne-compatible or not, continue to proliferate.Therefore we felt it necessary to include information on shells similar to the Korn shell. This Appendix summarizes the differences between the Korn shell and the following shells:
-
The System V Release 4 Bourne shell, as a kind of baseline
-
The 1988 version of the Korn shell
-
The IEEE POSIX 1003.2 Shell Standard, to which the Korn shell and other shells adhere
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- The Bourne Shell
- InhaltsvorschauThe Korn shell is almost completely backward-compatible with the Bourne shell. The only significant feature of the latter that the Korn shell doesn't support is
^(caret) as a synonym for the pipe (|) character. This is an archaic feature that the Bourne shell includes for its own backward compatibility with earlier shells. No modern Unix version has any shell code that uses^as a pipe.To describe the differences between the Bourne shell and the Korn shell, we'll go through each chapter of this book and enumerate the features discussed in the chapter that the Bourne shell does not support.- Chapter 1
-
The
cdold new andcd -forms of the cd command.Tilde (~) expansion.The Bourne shell always follows the physical file layout, which affects what happens when youcd ..out of somewhere that was a symbolic link.The built-in commands don't have online help.Some older versions of the Bourne shell don't support the jobs command and job control, or they may require being invoked as jsh in order to enable job control features. - Chapter 2
-
All (i.e., the Bourne shell doesn't support any of the history and editing features discussed in Chapter 2).
- Chapter 3
-
Aliases are not supported.set -o options don't work. The Bourne shell supports the abbreviations listed in the "Options" table in Appendix B, except -A, -b, -C, -m, -p, and -s.Environment files aren't supported; neither is the print command (use echo instead). The following built-in variables aren't supported:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - The 1988 Korn Shell
- InhaltsvorschauPerhaps the most obvious shell with which to compare ksh93 is ksh88, the 1988 version of the Korn shell. This section briefly describes those features of ksh93 that are either different or nonexistent in ksh88. As with the presentation for the Bourne shell, the topics are covered in the same order as they're presented in the rest of the book.
- Chapter 1
-
The built-in help facilities (such as -?, --man, and so on) are not available.Tilde substitution does not occur during variable expansion (
${var op word}). - Chapter 2
-
CTRL-T works differently in emacs editing mode. In ksh88, it transposes the two characters to the right of point and moves point forward by one character.In emacs-mode, ESC ESC, ESC
*, and ESC=don't work on the first word of a command line, i.e., there is no command completion facility. The ESC#command always prepends a#character. It never removes them.Similarly, in vi-mode, the*,\and=commands don't work on the first word of a command line, and the#command always prepends a#character. It never removes them.Finally, there is no variable completion, the hist command is called fc,FCEDITis used in place ofHISTEDIT, and theHISTCMDvariable is not available. - Chapter 3
-
The
ENVfile is sourced for all shells, and ksh88 only does variable substitution on the value of$ENV.Alias tracking can be turned off in ksh88.The -p option to alias is not present in ksh88, nor is the -a option to unalias.The following built-in variables aren't supported:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - The IEEE 1003.2 POSIX Shell Standard
- InhaltsvorschauThere have been many attempts to standardize Unix. Hardware companies' monolithic attempts at market domination, fragile industry coalitions, marketing failures, and other such efforts are the stuff of history — and the stuff of frustration.Only one standardization effort has not been tied to commercial interests: the Portable Operating System Interface, known as POSIX. This effort started in 1981 with the /usr/group (now UniForum) Standards Committee, which produced the /usr/group Standard three years later. The list of contributors grew. Eventually, the effort to create a formal standard moved under the umbrella of the Institute of Electrical and Electronic Engineers (IEEE) and the International Organization for Standardization (ISO).The first POSIX standard was published in 1988 and revised in 1996. This one, called IEEE Standard 1003.1, covered low-level issues at the system call level. IEEE Standard 1003.2, covering the shell, utility programs, and user interface issues, was ratified in September 1992 after a six-year effort. In September 2001, a joint revision of both standards was approved. The new standard, covering all the material in the two earlier separate documents, is known as IEEE Standard 1003.1-2001.The POSIX standards were never meant to be rigid and absolute. The committee members certainly weren't about to put guns to the heads of operating system implementers and force them to adhere. Instead, the standards are designed to be flexible enough to allow for both coexistence of similar available software, so that existing code isn't in danger of obsolescence, and the addition of new features, so that vendors have the incentive to innovate. In other words, they are supposed to be the kind of third-party standards that vendors might actually be interested in following.As a result, most Unix vendors currently comply with both standards. The Korn shell is no exception; it is intended to be 100% POSIX-compliant. It pays to be familiar with what's in the standard if you want to write code that is portable to different systems.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
- dtksh
- InhaltsvorschauThe Desk Top Korn Shell (dtksh) is a standard part of the Common Desktop Environment (CDE), available on commercial Unix systems such as Solaris, HP-UX, and AIX. It is based on a somewhat older version of ksh93. It evolved from the earlier program wksh, the Windowing Korn shell, released by Unix System Laboratories in late 1992. It's a full Korn shell, compatible with the version that this book describes, that has extensions for graphical user interface (GUI) programming in the X Window System environment. It is typically found in /usr/dt/bin/dtksh.dtksh supports the OSF/Motif graphical Toolkit by making its routines available as built-in commands. This allows programmers to combine the Korn shell's strength as a Unix systems programming environment with the power and abstraction of the Toolkit. The result is a unified environment for quick and easy development of graphics-based software.There are various GUI development tools that allow you to construct user interfaces with a graphics-based editor rather than with programming language code. But such tools are typically huge, expensive, and complex. dtksh, on the other hand, is inexpensive and unbeatable for the smoothness of its integration with Unix — it's the only such tool that you can use as your login shell! (Well, almost; see the next section.) It is a definite option for systems programmers who use X-based workstations and need a rapid prototyping tool.To give you the flavor of dtksh code, here is a script that implements the canonical "Hello World" program by displaying a small box with an "OK" button. It is from the article Graphical Desktop Korn Shell, in the July, 1998 issue of Linux Journal, by George Kraft IV. (See
http://www.linuxjournal.com/article.php?sid=2643.) This code should hold no surprises for X and Motif programmers:#!/usr/dt/bin/dtksh XtInitialize TOPLEVEL dtHello DtHello "$@" XmCreateMessageDialog HELLO $TOPLEVEL hello \ dialogTitle:"DtHello" \ messageString:"$(print "Hello\nWorld")" XmMessageBoxGetChild HELP $HELLO \ DIALOG_HELP_BUTTON XtUnmanageChild $HELP XmMessageBoxGetChild CANCEL $HELLO \ DIALOG_CANCEL_BUTTON XtUnmanageChild $CANCEL XtAddCallback $HELLO okCallback exit XtManageChild $HELLO XtMainLoopEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - tksh
- InhaltsvorschauBack in 1996, while a computer science graduate student at Princeton University, Dr. Jeffrey L. Korn wrote tksh. This is an integration of ksh93 with Tcl/Tk. The following quote (from Dr. Korn's research web page) summarizes it well:Tksh is a graphical language (similar to Visual Basic or Tcl/Tk) that uses KornShell (ksh93) for scripting and Tk for graphical user interface. Tksh is implemented as a ksh93 extension, and allows Tcl libraries such as Tk to run on top of ksh93 unchanged. ksh93 is well suited for graphical scripting because it is backward compatible with sh, making it both easy to learn and easy to extend existing scripts to provide user interface. Tksh also allows Tcl scripts to run without modification, making it possible to mix and match components written in either Tcl or ksh93.The tksh home page is still at Princeton:
http://www.cs.princeton.edu/~jlk/tksh/. It has links to papers and documentation that can be downloaded and printed. However, the link to tksh executables is out-of-date. The tksh source is available from AT&T Research as part of the ast-open package, which also contains ksh93 and reimplementations of many other Unix tools. See Appendix C for more information.The following example script, from the USENIX paper on tksh, is called watchdir:# Tksh Demo # Jeff Korn # # This script keeps track of visited directories and shows the files # in the current directory. You can double-click on files and # directories. The script should be used interactively, so to run: # $ tksh # $ . scripts/watchdir function winsetup { pack $(frame .f) frame .f.dirname -relief raised -bd 1 pack .f.dirname -side top -fill x pack $(frame .f.ls) $(frame .f.dirs) -side left label .f.dirname.label -text "Current directory: " label .f.dirname.pwd -textvariable PWD pack .f.dirname.label .f.dirname.pwd -side left scrollbar .f.ls.scroll -command ".f.ls.list yview" listbox .f.ls.list -yscroll ".f.ls.scroll set" -width 20 -setgrid 1 pack $(label .f.ls.label -text "Directory Contents") -side top pack .f.ls.list .f.ls.scroll -side left -fill y -expand 1 scrollbar .f.dirs.scroll -command ".f.dirs.list yview" listbox .f.dirs.list -yscroll ".f.dirs.scroll set" -width 20 -setgrid 1 pack $(label .f.dirs.label -text "Visited Directories") -side top pack .f.dirs.list .f.dirs.scroll -side left -fill y -expand 1 bind .f.dirs.list "<Double-1>" 'cd $(selection get)' bind .f.ls.list "<Double-1>" 'tkfileselect $(selection get)' } function tkfileselect { [[ -d "$1" ]] && tkcd "$1" [[ -f "$1" ]] && ${EDITOR-${VISUAL-emacs}} "$1" } function tkcd { cd $1 > /dev/null || return .f.ls.list delete 0 end set -o markdirs .f.ls.list insert end .. * [[ ${VisitedDir["$PWD"]} == "" ]] && .f.dirs.list insert end "$PWD" VisitedDir["$PWD"]=1 } typeset -A VisitedDir winsetup > /dev/null alias cd=tkcd tkcd .Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - pdksh
- InhaltsvorschauMany of the Open Source Unix-like systems, such as GNU/Linux, come with the Public Domain Korn Shell, pdksh. pdksh is available as source code; start at its home page:
http://www.cs.mun.ca/~michael/pdksh/. It comes with instructions for building and installing on various Unix platforms.pdksh was originally written by Eric Gisin, who based it on Charles Forsyth's public-domain clone of the Version 7 Bourne shell. It is mostly compatible with the 1988 Korn shell and POSIX, with some extensions of its own.Its emacs editing mode is actually more powerful than that of the 1988 Korn shell. Like the full Emacs editor, you can customize the keystrokes that invoke editing commands (known as key bindings in Emacs terminology). Editing commands have full names that you can associate with keystrokes by using the bind command.For example, if you want to set up CTRL-U to do the same thing as CTRL-P (i.e., go back to the previous command in the history file), you could put this command in your .profile:bind '^U'=up-history
You can even set up two-character escape sequences, which (for example) allow you to use ANSI arrow keys as well as control characters, and you can define macros, i.e., abbreviations for sequences of editing commands.The public domain Korn shell's additional features include alternation wildcards (borrowed from the C shell) and user-definable tilde notation, in which you can set up~as an abbreviation for anything, not just user names. There are also a few subtle differences in integer expression evaluation and aliasing.pdksh lacks the following features of the official version:-
The built-in variable
LINES. -
The DEBUG fake signal. The fake signals ERR and EXIT within functions.
-
Functions inherit the trap settings of the main script.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- bash
- Inhaltsvorschaubash is probably the most popular "third-party" shell that is available for Unix and other systems. In particular, it is the default shell on GNU/Linux systems. (It also comes on the "freeware" CD with Solaris 8.) You can get it from the Internet, via anonymous FTP to
ftp.gnu.orgin the directory /pub/gnu/bash. You can also order it from its maker at the address listed here.The Free Software Foundation 59 Temple Place - Suite 330 Boston, MA 02111-1307 (617) 542-2652 (617) 542-5942 (fax) gnu@gnu.org
http://www.gnu.orgBash was written by Brian Fox and Chet Ramey. Chet Ramey currently maintains it. Its name is in line with the FSF's penchant for bad puns: it stands for Bourne-Again Shell. Although bash is easily available and you don't have to pay for it (other than the cost of media, phone calls, etc.), it's not really public domain software. While public domain software doesn't have licensing restrictions, the FSF's software does. But those restrictions are diametrically opposed to those in a commercial license: instead of agreeing not to distribute the software further, you agree not to prevent it from being distributed further! In other words, you enjoy unrestricted use of the software as long as you agree not to inhibit others from doing the same. Richard Stallman, the founder of the FSF, invented this intriguing and admirable concept.These days, the ideals of the Free Software and Open Source movements, the GNU project, and the quality of GNU software are all well known. The most popular GNU system is GNU/Linux, which uses the Linux kernel and GNU utilities to make a complete, fully functional, Unix- and POSIX-compatible computing environment.bash is fully compatible with the 1992 POSIX standard. It has several of the most important Korn shell features and the C shell features that the Korn shell has appropriated, including aliases, functions, tilde notation, emacs and vi editing modes, arithmetic expressions, job control, etc.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - zsh
- Inhaltsvorschauzsh is a powerful interactive shell and scripting language with many features found in ksh, bash, and tcsh, as well as several unique features. zsh has most of the features of ksh88 but few of ksh93. It is freely available and should compile and run on just about any modern version of Unix. Ports for other operating systems are also available. The zsh home page is
http://www.zsh.org. The current version is 4.0.2.In this section we cover:-
Extended globbing
-
Completion
-
Command-line editing
-
Prompts and prompt themes
-
Differences between zsh and ksh
A very useful feature is the recursive glob operator,**. For example, a recursive grep is simple to construct:grep foo **/*.c
Or to recursively find all files or directories named core, try:print **/core
Another useful feature is glob qualifiers. There are many of these, for example, to print out only regular files in the current directory:print *(.)
or just the directories:print *(/)
Combining these with the recursive glob operator can be handy. We can improve the above example of finding core files by limiting the search to regular files only:print **/core(.)
Another qualifier isUfor file system objects you own. The following prints all files you own in /tmp and below:print /tmp/**/*(U)
The glob qualifiers can also be combined. For example, using the socket file keyword=in combination withU, it's easy to find socket files in /tmp and below that you own:print /tmp/**/*(U=)
File size qualifiers are also available. For example, to find all files in your home directory that are greater than 10 megabytes in size:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Workalikes on PC Platforms
- InhaltsvorschauThe proliferation of the Korn shell has not stopped at the boundaries of Unix-dom. Many programmers who got their initial experience on Unix systems and subsequently crossed over into the PC world wished for a nice Unix-like environment (especially when faced with the horrors of the MS-DOS command line!), so it's not surprising that several Unix shell-style interfaces to small-computer operating systems have appeared, Korn shell emulations among them.In the past several years, not just shell clones have appeared, but entire Unix "environments." Two of them use shells that we've already discussed. Two others provide their own shell reimplementations. Providing lists of major and minor differences is counterproductive. Instead, this section describes each environment in turn (in alphabetical order), along with contact and Internet download information.Cygnus Consulting (now Red Hat), created the cygwin environment. First creating cgywin.dll, a shared library that provides Unix system call emulation, they ported a large number of GNU utilities to various versions of Microsoft Windows. The emulation includes TCP/IP networking with the Berkeley socket API. The greatest functionality comes under Windows/NT, Windows 2000, and Windows XP, although the environment can and does work under Windows 95/98/ME, as well.The cygwin environment uses bash for its shell, GCC for its C compiler, and the rest of the GNU utilities for its Unix toolset. A sophisticated mount command provides a mapping of the Windows
C:\pathnotation to Unix filenames.The starting point for the cygwin project ishttp://www.cygwin.com. The first thing to download is an installer program. Upon running it, you choose what additional packages you wish to install. Installation is entirely Internet-based; there are no official cygwin CD's, at least not from the project maintainers.The DJGPP suite provides 32-bit GNU tools for the MS-DOS environment. To quote the web page:Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Appendix B: Reference Information
- InhaltsvorschauThis appendix contains reference lists for invocation options, built-in commands and keywords, predefined aliases, built-in shell variables, test operators, shell options, typeset options, arithmetic, emacs-mode commands, and vi-mode control commands. Furthermore, it describes how to use the full facilities of the built-in getopts command.
Section B.1: Invocation Options
Section B.2: Built-in Commands and Keywords
Section B.3: Predefined Aliases
Section B.4: Built-in Shell Variables
Section B.5: Test Operators
Section B.6: Options
Section B.7: Typeset Options
Section B.8: Arithmetic
Section B.9: Emacs Mode Commands
Section B.10: vi Control Mode Commands
Section B.11: Using getopts
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Invocation Options
- InhaltsvorschauHere is a list of the options you can use when invoking the Korn shell. In addition to these, any set option can be used on the command line; see the table on options later in this appendix. Login shells are usually invoked with the options -i (interactive), -s (read from standard input), and -m (enable job control).
Option Meaning -cstringExecute string, then exit. -DPrint all$"..."strings in the script. This is for use in creating a database of locale-specific translations of strings in a script.-iInteractive shell. Ignore signals TERM, INTR, and QUIT. -rRestricted shell. See Chapter 10. -RfilenameCreate a cross-reference database for variable and command definitions in filename. May not be compiled in.-sRead commands from the standard input. If an argument is given, this flag takes precedence (i.e., the argument won't be treated as a script name and standard input will be read).Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Built-in Commands and Keywords
- InhaltsvorschauHere is a summary of all built-in commands and keywords.
Name Command/keyword Chapter Summary !Keyword 5 Invert the true/false result of the following pipeline. :Command 7 Do nothing (just do expansions of arguments). .Command 4 Read file and execute its contents in current shell. alias Command 3 Set up shorthand for command or command line. bg Command 8 Put job in background. builtin Command Add or remove built-in commands; print information about them.break Command 5 Exit from surroundingfor,select,while, oruntilloop.caseKeyword 5 Multiway conditional construct. cd Command 1 Change working directory. command Command 5 Locate built-in and external commands; find a built-in command instead of an identically named function.continue Command 4 Skip to next iteration offor,select,while, oruntilloop.disown Command 8 Disassociate a background job from the current shell. The effect is that the job is not sent the HUP signal when the shell exits.echo Command 4 Expand and print arguments (obsolete). exec Command 9 Replace shell with given program. Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Predefined Aliases
- InhaltsvorschauA number of aliases are predefined, i.e. automatically built-in to ksh at compile time. They are listed in the table below. Note that some of them are defined with a trailing space character. This enables alias expansion on the word following the alias on the command line.
Name Chapter Full value autoload 4, 6 alias autoload='typeset -fu'command 7 alias command='command 'fc 2 alias fc=histfloat 6 alias float='typeset -E'functions 6 alias functions='typeset -f'hash 3 alias hash='alias -t --'history 2 alias history='hist -l'integer 6 alias integer='typeset -i'nameref 4 alias nameref='typeset -n'nohup 3, 8 alias nohup='nohup 'r 2 alias r='hist -s'redirect 9 alias redirect='command exec'stop 8 alias stop='kill -s STOP'Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Built-in Shell Variables
- InhaltsvorschauHere is a summary of all built-in shell variables:
Variable Chapter Meaning #4 Number of arguments given to current process. @4 Command-line arguments to current process. Inside double quotes, expands to individual arguments.*4 Command-line arguments to current process. Inside double quotes, expands to a single argument.-(hyphen)Options given to shell on invocation. ?5 Exit status of previous command. $8 Process ID of shell process. _(underscore)3 Inside$MAILPATH: the filename that triggered a "you have mail" message. On the command line: last argument to previous command. Inside a script: the full pathname used to find and run the script.!8 Process ID of last background command. .sh.edchar10 Characters entered when processing a KEYBD trap..sh.edcol10 Position of the cursor in the most recent KEYBD trap..sh.edmode10 Equal to ESC in vi-mode, empty otherwise..sh.edtext10 Characters in the input buffer during a KEYBD trap..sh.match4 Array variable with text that matched pattern in variable substitution. (Starting withEnde der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Test Operators
- InhaltsvorschauThese are the operators that are used with the
[[...]]construct. They can be logically combined with&&("and") and||("or") and grouped with parenthesis. When used with filenames of the form/dev/fd/N, they test the corresponding attribute of open file descriptor N.Operator True if... -afilefile exists. (Obsolete.-eis preferred.)-bfilefile is a block device file. -cfilefile is a character device file. -Cfilefile is a contiguous file. (Not for most Unix versions.)-dfilefile is a directory. -efilefile exists. -ffilefile is a regular file. -gfilefile has its setgid bit set. -Gfilefile's group ID is the same as the effective group ID of the shell.-hfilefile is a symbolic link. -kfilefile has its sticky bit set. Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Options
- InhaltsvorschauThese are options that can be turned on with the set -o command. All are initially off except where noted. Abbreviations, where listed, are options to set that can be used instead of the full set -o command (e.g.,
set -ais an abbreviation forset -o allexport). For the most part, the abbreviations are actually backward-compatible Bourne shell options. To disable an option, use set +o long-name or set +X, where long-name and X are the long form or the single character form of the option, respectively.Option Abbrev Meaning allexport -aExport all subsequently defined variables.bgnice Run all background jobs at decreased priority (on by default).emacs Use Emacs-style command-line editing.errexit -eExit the shell when a command exits with nonzero status.gmacs Use Emacs-style command-line editing, but with a slightly different meaning for CTRL-T (See Chapter 2).ignoreeof Disallow CTRL-D to exit the shell.keyword -kExecute assignments in the middle of command lines. (Very obsolete.)markdirs Add / to all directory names generated from wildcard expansion.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Typeset Options
- InhaltsvorschauThese are the options to the typeset command. Use
+option to turn an option off, e.g.,typeset +x footo stop exporting the variablefoo.Option Meaning With no option, create local variable within function. -ADeclare variable as an associative array. -E[n]Declare variable as a floating-point number. Optional n is number of significant figures.-F[n]Declare variable as a floating-point number. Optional n is number of significant digits.-fWith no arguments, prints all function definitions. -ffnamePrint the definition of function fname. +fPrint all function names. -ftTurn on trace mode for named function(s). +ftTurn off trace mode for named function(s). -fuDefine given name(s) as autoloaded function(s). -fxObsolete; does nothing in ksh93. -HUnix to host filename mapping for non-Unix system. -i[n]Declare variable as an integer. Optional n is output base.-lConvert all letters to lowercase. -LLeft-justify and remove leading spaces. -nDeclare variable as a nameref. -pPrint typeset commands to re-create variables with the same attributes.Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Arithmetic
- InhaltsvorschauStarting with ksh93m, the built-in arithmetic facility understands a large percentage of the C language's expressions. This makes the shell more attractive as a full-blown programming language. The following features are available:
- Trailing type suffixes
-
Integer constants can have a trailing
UorLsuffix to indicate that they are unsigned or long, respectively. While the lowercase versions may also be used, this is not recommended, since it is easy to confuse anl(letter ell) with a1(digit one). - C character constants
-
C single-quoted character constants are recognized. As in C, they act like integer constants. For example:
$ typeset -i c $ for ((c = 'a'; c <= 'z'; c++)) > do print $c > done 97 98 99 100 ...
- Octal and hexadecimal constants
-
You can use the C format for octal (base 8) and hexadecimal (base 16) constants. Octal constants start with a leading
0, and hexadecimal constants start with a leading0xor0X. For example:$ print $((010 + 1)) Octal 10 is decimal 8 9 $ print $((0x10 + 1)) Hexadecimal 10 is decimal 16 17 - Unsigned integer arithmetic
-
By using typeset -ui, you can create unsigned integers. Regular integers represent both positive and negative numbers. Unsigned integers start at 0, go up to some implementation-dependent value, and then "wrap" around again to 0. Similarly, subtracting 1 from 0 wraps around the other way, yielding the largest unsigned number:
$ typeset -ui u=0 $ let u-- $ print $u 4294967295
- C operators and precedence
-
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Emacs Mode Commands
- InhaltsvorschauHere is a complete list of all emacs editing mode commands. Some of these, such as "ESC [ A," represent ANSI standard terminal arrow key sequences; they were added for ksh93h.
Command Meaning CTRL-A Move to beginning of line CTRL-B Move backward one character without deleting CTRL-C Capitalize character after point CTRL-D Delete one character forward CTRL-E Move to end of line CTRL-F Move forward one character CTRL-I (TAB) Do filename completion on current word (starting with ksh93h)CTRL-J Same as ENTER. CTRL-K Delete ("kill") forward to end of line CTRL-L Redisplay the line CTRL-M Same as ENTER CTRL-N Next line CTRL-O Same as ENTER, then display next line in history file CTRL-P Previous line CTRL-R Search backward CTRL-T Transpose the two characters on either side of point CTRL-U Repeat the following command four times CTRL-V Print the version of the Korn shell CTRL-W Delete ("wipe") all characters between point and markCTRL-X CTRL-E Invoke the emacs program on the current commandCTRL-X CTRL-X Exchange point and mark CTRL-Y Retrieve ("yank") last item deleted CTRL-] x Search forward for x, where x is any character CTRL-@ Set mark at point DEL Delete one character backward CTRL-[ Same as ESC (most keyboards) ESC b Move one word backward ESC c Change word after point to all capital letters ESC d Delete one word forward ESC f Move one word forward ESC h Delete one word backward ESC l Change word after point to all lowercase letters ESC p Save characters between point and mark as if deleted ESC CTRL-H Delete one word backward ESC CTRL-] x Search backward for x, where x is any characterESC SPACE Set mark at point ESC # Insert line in history file for future editing ESC DEL Delete one word backward ESC < Move to first line of history file ESC > Move to last line of history file Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - vi Control Mode Commands
- InhaltsvorschauHere is a complete list of all vi-mode control commands. As for the emacs mode commands, the sequences such as "[ A" are for ANSI standard terminal arrow keys and were added for ksh93h.
Command Meaning hMove left one character [ DMove left one character (ksh93h and newer) lMove right one character space Move right one character [ CMove right one character (ksh93h and newer) wMove right one word bMove left one word WMove to beginning of next nonblank word BMove to beginning of preceding nonblank word eMove to end of current word EMove to end of current nonblank word 0Move to beginning of line [ HMove to beginning of line (ksh93h and newer) ^Move to first nonblank character in line $Move to end of line [ YMove to end of line (ksh93h and newer) iInsert text before current character aInsert text after current character IInsert text at beginning of line AInsert text at end of line rReplace one character (doesn't enter input mode) ROverwrite existing text Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Using getopts
- InhaltsvorschauThe getopts command is extremely capable. With it, you can make your shell scripts accept long options, specify that arguments are optional or numeric, and provide descriptions of the arguments and values such that the -?, --man, --html and --nroff options work the same for your program as they do for the ksh93 built-in commands.The price for this power is the complexity of the option description "language." Based on a description provided by Dr. Glenn Fowler of AT&T Research, we describe how the facilities evolved, how they work, and summarize how to use them in your own programs. We use the the extended getopts command in the solution to Task B-1.The first step is to describe the options. This is done with a comment at the top of the script:
# usage: phaser4 [ options ] files # -k, --kill use kill setting (default) # -l n, --level n set phaser level (default = 2) # -s, --stun use stun-only setting # -t [lf], --tricorder [lf] tricorder mode, opt. scan for life form lf
Now the fun begins. This outline of capabilities follows the order in which features were added to getopts.-
Start with the getopts command as described in Chapter 6. This yields a simple option string that only allows one-letter options:
USAGE="kl#st:" while getopts "$USAGE" optchar ...
-
Add a textual description for the option argument. This is done by enclosing arbitrary text in between
[and]:USAGE="kl#[level]st:[life_form]" while getopts "$USAGE" optchar ...
-
Allow a default value for an option's argument. This is done by specifying
:=value within the description in between the brackets:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Appendix C: Building ksh from Source Code
- InhaltsvorschauThis appendix describes how to download binaries for ksh93, as well as how to download the source code for ksh93 and build a working version. You should do this if your system does not have ksh93 at all or if you need any of the features that are only available in the most recent releases.
Section C.1: Korn Shell Web Sites
Section C.2: What You Can Download
Section C.3: Building ksh
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Korn Shell Web Sites
- InhaltsvorschauThe starting place for all things related to the Korn shell is
http://www.kornshell.com, maintained by David Korn, with links grouped by the following topics:- Information
-
Clicking this link leads to a one-page overview on the Korn shell.
- Software
-
Clicking this link leads to pointers to the AT&T download site (see the next section), some sample code, an online article for dtksh, and a link for tksh. These last two are described in Appendix A.
- Documentation
-
This link leads to a page with pointers to online info, including general information, man pages for both ksh88 and ksh93, books and references on the Korn shell, and papers about the Korn shell from various conferences.
- Resources
-
A list of links to other WWW resources for ksh and many of the other shells described in Appendix A, such as bash and dtksh.
- Fun
-
David G. Korn, the programmer, meets KoRN, the rock group. 'Nuff said.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - What You Can Download
- Inhaltsvorschau
http://www.research.att.com/sw/downloadis the starting point for actually downloading the ksh software. The software is covered by an Open Source-style license. The current version of the license is athttp://www.research.att.com/sw/license/ast-open.html. This license is reproduced in Appendix D. You should read and understand it first; if its terms aren't acceptable to you, you should not download the software source code or binaries from the AT&T web site.The software on the AT&T web site is available in different "packages," most of which have names prefixed with "ast," which stands for "Advanced Software Tools." The source packages come as gziped tar files, using the .tgz file name suffix. Choose one or more of the following packages to download:- ratz
-
A standalone executable program for reading gziped tar files. Use this if you don't have gzip on your system and don't want to go to the trouble to first download and build gzip. You may download source code for this package or a binary executable for any of the architectures listed in Table C-1.
- ksh
-
This is the fastest way to get a ksh93 executable. Versions are available for the architectures listed in Table C-1.
- INIT
-
This package must be downloaded when building any of the following source packages. It contains the files and directory structures that the AST tools and build system rely upon.
- ast-ksh
-
This package builds just the support infrastructure (libraries, environment test programs, etc.) for ksh and the ksh executable. It is the simplest thing to build.
- ast-base
-
This package builds everything in the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. - Building ksh
- InhaltsvorschauBuilding any of the packages from source code is pretty straightforward. The full details, with a FAQ and notes, are given on the AT&T web site. Here is a walk-through of the steps. We show the steps for the ast-open package, but they're identical for the other source code packages.
-
Make sure you have a C compiler for your system. An ANSI/ISO C compiler is preferred, but a K&R compiler will work too. Getting a C compiler if you don't have one is beyond the scope of this book; contact your local system administrator.
-
Download the package(s) you wish to build into an otherwise empty directory. Here, we build the ast-open package from October 31, 2001:
$ ls INIT.2001-10-31.tgz ast-open.2001-10-31.tgz
-
Make the directory lib/package/tgz and move the files there:
$ mkdir lib lib/package lib/package/tgz $ mv *.tgz lib/package/tgz -
Extract the INIT package manually:
$ gzip -d < lib/package/tgz/INIT.2001-10-31.tgz | tar -xvpf - \r\v\vNOTICE -- LICENSED SOFTWARE -- SEE README FOR DETAILS\r\v\v README src/Makefile src/cmd/Makefile src/lib/Makefile ...
If you don't have gzip, use the ratz program, as described earlier. -
Initialize the list of available packages:
$ bin/package read \r\v\vNOTICE -- LICENSED SOFTWARE -- SEE README FOR DETAILS\r\v\v README src/Makefile src/cmd/Makefile src/lib/Makefile src/Mamfile ...
-
Start the compilation. This step is quite verbose and will take a while. Exactly how long depends upon the speed of your system and compiler, and upon which package you are building:
$ bin/package make package: initialize the /home/arnold/ast-open/arch/linux.i386 view package: update /home/arnold/ast-open/arch/linux.i386/bin/proto package: update /home/arnold/ast-open/arch/linux.i386/bin/mamake package: update /home/arnold/ast-open/arch/linux.i386/bin/ratz package: update /home/arnold/ast-open/arch/linux.i386/bin/release ...
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
- Appendix D: AT&T ast Source Code License Agreement
- Inhaltsvorschau
SOURCE CODE AGREEMENT Version 1.2D
PLEASE READ THIS AGREEMENT CAREFULLY. By accessing and using the Source Code, you accept this Agreement in its entirety and agree to only use the Source Code in accordance with the following terms and conditions. If you do not wish to be bound by these terms and conditions, do not access or use the Source Code.-
YOUR REPRESENTATIONS
-
You represent and warrant that:
-
If you are an entity, or an individual other than the person accepting this Agreement, the person accepting this Agreement on your behalf is your legally authorized representative, duly authorized to accept agreements of this type on your behalf and obligate you to comply with its provisions;
-
You have read and fully understand this Agreement in its entirety;
-
Your Build Materials are either original or do not include any Software obtained under a license that conflicts with the obligations contained in this Agreement;
-
To the best of your knowledge, your Build Materials do not infringe or misappropriate the rights of any person or entity; and,
-
You will regularly monitor the Website for any notices.
-
-
-
DEFINITIONS AND INTERPRETATION
-
For purposes of this Agreement, certain terms have been defined below and elsewhere in this Agreement to encompass meanings that may differ from, or be in addition to, the normal connotation of the defined word.
-
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar. -
Zurück zu Learning the Korn Shell
