Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ ksh(1) — A/UX 3.0.1

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

cat(1)

chmod(1)

CommandShell(1)

csh(1)

echo(1)

ed(1)

env(1)

getopt(1)

kill(1)

launch(1)

login(1)

newgrp(1)

nice(1)

printenv(1)

ps(1)

sh(1)

startmac(1)

stty(1)

tee(1)

vi(1)

dup(2)

exec(2)

fork(2)

ioctl(2)

lseek(2)

pipe(2)

ulimit(2)

umask(2)

wait(2)

signal(3)

rand(3C)

a.out(4)

passwd(4)

profile(4)

termcap(4)

terminfo(4)

environ(5)




ksh(1) ksh(1)
NAME ksh - runs the Korn shell, an enhanced command interpreter that is backward-compatible with the Bourne shell (sh) SYNOPSIS ksh [-a] [-c string] [-e] [-f] [-h] [-i] [-k] [-m] [-n] [-o option]... [-p] [--positional-arg]... [+positional-arg]... [-r] [-s] [-t] [-u] [-v] [-x] [file]... ARGUMENTS + [positional-arg]... - [positional-arg]... Turn off -x and -v options and suppress examination of remaining shell arguments for interpretation as command options. Instead, the positional variables of the shell are reassigned in terms of the positional-arg values supplied, which makes it possible to set $1 to a value beginning with a hyphen. -- [positional-arg]... Reassigns the positional variables. The remaining arguments are positional parameters and are assigned, in order, to $1, $2, and so on. If no arguments follow this option, the positional parameters are unset. -a Exports the new values for any subsequently modified variables without your having to use an explicit export command. -c string Specifies a command line (string) that you want the ksh subshell to run before exiting. Using this option is one way to run the Korn shell noninteractively. -e Executes the command associated with the ERR condition by the trap command, if any was set. Exits if a command returns false. This mode is disabled while the system is reading the startup files (.kshrc and .profile). -f Disables filename generation. (See ``Filename Generation'' in the ``Description'' section later in this manual page.) file Specifies the filename for a shell script you want the ksh subshell to run before exiting. -h Affects the way the built-in alias command builds aliases. The command-name portion of the aliased command is expanded into a full pathname so that the alias can continue to locate the same command program January 1992 1



ksh(1) ksh(1)
even when identically named commands are later created and located in directories that are also part of the search path. An alias built in this fashion is a tracked alias. See ``Aliasing'' in the ``Description'' section for more information about tracked aliases. -i Establishes an interactive mode of operation. -k Establishes a mode of operation where any command-line elements that are variable assignments are placed in the environment of a command, regardless of their position on the command line. Otherwise, only variable assignments that precede the command name are placed in the environment of a command. -m Causes background jobs to run in a separate process group that is not associated with the terminal. The exit status of background jobs is reported in a completion message. This mode is turned on automatically for interactive shells. -n Reads commands and checks them for syntax errors, but does not execute them. This option is ignored for interactive shells. -o [option] Puts into effect the option specified. With no option arguments, -o prints the current preference settings. The option letters corresponding to the active settings are also merged into a single string that is stored in the variable named ``hyphen'' ($-). To set or unset these options once an interactive session is underway, use set as described in ``Built-in Commands'' in the ``Description'' section later in this manual page. You can replace option with any of the following values: allexport Exports variables automatically whenever they are reset; establishes the same operating mode as does the -a option. bgnice Runs all background jobs at a lower priority. emacs Establishes an emacs-style, command-input editor for command entry. errexit Executes the ERR trap; establishes the same 2 January 1992



ksh(1) ksh(1)
operating mode as does the -e option. gmacs Establishes a gmacs-style, command-input editor for command entry. ignoreeof Prevents ksh from exiting when an end-of-file character is received. The exit command must be explicitly executed. keyword Affects the way parameters are placed in the environment; establishes the same operating mode as does the -k option. markdirs Appends a trailing slash (/) to all directory names resulting from filename generation. monitor Alters the usual process group assigned to background jobs; establishes the same operating mode as does the -m option. noclobber Prevents the overwriting of existing files when output is redirected to files. noexec Checks command lines without executing them; establishes the same operating mode as does the -n option. Using noexec helps you determine whether ksh can interpret an input data stream as valid commands. noglob Disables filename generation; establishes the same operating mode as does the -f option. nolog Prevents ksh from saving function definitions in the history file. nounset Causes an error to be reported when an uninitialized variable is referenced within a command line; establishes the same operating mode as does the -u option. privileged Resets PATH to the default search path; January 1992 3



ksh(1) ksh(1)
establishes the same operating mode as does the -p option. trackall Tracks aliases by way of storing the full pathname to the aliased command; establishes the same operating mode as does the -h option. verbose Prints each command line (exactly as it appears in the input) before it is executed; establishes the same operating mode as does the -v option. vi Establishes a command-line-input editor for command entry. This is also called the ``cooked'' (processed) mode. This editor has fewer features than the viraw editor, and thus has faster response time than it. viraw Establishes a command-character-input editor for command entry similar to the vi argument, except that input is processed on a character-by- character basis. This editor mode is also known as the ``raw'' mode. The viraw editor has more features and is more reliable, but causes longer response times for all users on multi-user systems. This editor has horizontal scrolling and Tabs are always expanded. xtrace Prints each command and its arguments after those arguments have been processed for metacharacters but just prior to the execution of the command; establishes the same operating mode as does the -x option. -p Resets the PATH variable to the system default value, disables processing of the $HOME/.profile file, and uses the file /etc/suid_profile instead of the ENV file. This mode is automatically enabled whenever the effective user ID (or group ID) is not equal to the real user ID (or group ID). -r Restricts certain shell functions. The following actions are not allowed: (1) changing the directory; (2) setting the value of SHELL, ENV, or PATH; (3) specifying path or command names containing /; and (4) redirecting output by using > or >>. These restrictions are enforced after the .profile and ENV files are interpreted. 4 January 1992



ksh(1) ksh(1)
When you enter a command that ksh determines to be a shell script, the restricted shell invokes another instance of ksh to execute it. These secondary Korn shells are not restricted as is the parent shell. Thus, the restricted form of ksh allows shell scripts to run with more complete privileges despite the limitations of the parent shell. By administering the account so that certain setup actions are placed in .profile (where these restrictions are not yet enforced), an operating environment is established that precisely limits the actions that can be taken by its users. One of these setup actions should be to set the working directory to a designated directory other than the login directory. To maintain these security limitations, the so- designated working directory should deny the restricted account write permission. If write permission is granted for the designated working directory, then umask should be set to deny execute permission for any new files. Also, the system administrator usually sets up a new directory of commands. For example, /usr/rbin can be created and a limited number of links placed there so that /usr/bin can be made inaccessible for restricted accounts through their PATH variable setting in .profile. Applications intended for restricted account use should also be placed there. -s Ends the interactive mode of entering commands from standard input. Also, sorts the positional parameters when used with set -s, but not on the command line. -t Exits after reading and executing one command. -u Treats the presence of unset parameters as an error when substitution is necessary. -v Prints command lines exactly as they are read from the input, before shell metacharacters are interpreted. -x Prints commands and their arguments after shell metacharacters are interpreted, but prior to the execution of the command. DESCRIPTION ksh is a shell (or command interpreter) that accepts and dispatches command lines. It is largely responsible, along with CommandShell, for supporting the command-line interface of A/UX. Like the Macintosh Finder, the shell allows you to select the A/UX program or utility you want to run next, or January 1992 5



ksh(1) ksh(1)
to run it in conjunction with other programs that are already running. The ksh program is also one of the A/UX commands that you can run once an initial shell (command interpreter) is running. Using ksh this way is one method for switching between the different shell programs available. (See csh(1) and sh(1) for information about these other shells.) When you run the ksh command, the previously interactive shell is suspended until you exit the ksh subshell. To enter commands, you normally open a CommandShell window. When you do, CommandShell runs a shell to support the command-entry function in the window. The choice of shell is controlled by the preference variable SHELL, which is normally initialized along with other startup values in .login or .profile in your home directory. If SHELL is not set in one of those startup files, the shell spawned will be the same as your login shell (as described in passwd(4) and chsh(1)). This manual page treats ksh just like any other command despite the fact that you need a shell program to support the invocation of commands in the first place. You should become familiar with one or more of the shells to allow you to take advantage of the command capabilities of A/UX. As a prerequisite, you should learn about the CommandShell application (described in CommandShell(1) and A/UX Essentials). CommandShell supports the more visible and Macintosh-like elements of your system: the command windows, the mouse, and the menu functions at your disposal when you enter command lines. Using ksh For the shell program, the work of interpreting the commands you enter can be broken down into several steps: (1) prompting for and accepting lines of input; (2) deciphering the text of an input line, one unit of which is expected to be the name of a command; and (3) locating and running the (object) file containing the low-level instructions that give the command its functionality. The following three subsections that follow briefly discuss each of the three steps that make up a single computer-human interaction as mediated by a shell program (running interactively). Step one: obtaining input. To indicate its readiness to process a command, the shell displays a prompt message or symbol at the beginning of the line. You contribute to the text displayed on the command line by typing a command name after the prompt. During command entry, the shell displays 6 January 1992



ksh(1) ksh(1)
each character you type, placing it at the end of the command string and advancing the location of the cursor. During this time, the shell honors special characters that are not intended as part of the command string, such as the delete character (generated by the DELETE key). This ``silent'' conversation between you and the shell is limited to certain line-editing operations as well as the processing of other special characters such as the interrupt and end- of-line characters. The shell interprets these characters and takes appropriate action. Often this action changes the composition of the command string being displayed, as in the case of a delete character. The end-of-line (newline) character is generated when you press the RETURN key. When the shell received this character, it considers the command line to be complete. The command-line processing that the shell performs next is described in the next two subsections. While processing a command line, the shell does not display a new prompt, although the cursor may already be at the beginning of a new line. At any point during command-line processing and command execution until you see a new command prompt signaling completion, ksh honors an interrupt signal. Sometimes the generation of an interrupt signal results in the partial execution of the command or, if you are very quick, in no execution of the command. The interrupt character is typically the CONTROL-C key combination. See ``Controlling Foreground Jobs'' later in the ``Description'' section. Step two: deciphering input. The shell can recognize and correctly interpret a variety of command-line elements. Only very experienced programmers will know how to make the best use of all of the constructs that the shell is able to interpret. Most users do not need to learn all of these features in order to build useful command lines. The simplest acceptable command entry consists of the name of a command with no other elements, as shown in this example. (The $ symbol is the command prompt in this example.) $ date Tue Jun 18 12:01:25 PDT 1991 $ | In addition to the command name, command body may be required, depending on the command you are entering. The command body is subject to some processing by the shell, followed by final processing performed by the command program itself. The command body is typically broken down January 1992 7



ksh(1) ksh(1)
into two major elements, command options and arguments. The command options are typically individual letters. If you want to enter more than one command option, you normally merge the options into one character string. Whether you specify one or more command options, you must usually precede each option with a hyphen (-). Following the command options are the command arguments. Each argument is a string of characters, separated from one another or from the command options by a space or tab character, as shown here: command -options arguments When merged together, two or more command options can also be considered a single command argument, which can be formed into one string. With most commands, however, the options can be supplied as multiple space-separated strings, each consisting of a hyphen followed by a particular option letter: command -a -f -v The following command line includes one command option (-l) and one command argument (memofile) that is not a command option: ls -l memofile Most of the syntax descriptions that follow use the term command to refer to both the command name and its options and arguments. Often you can save yourself typing by relying on the shell to preprocess the command arguments in terms of substituting one element for lengthier text to which it refers. Sometimes one element will represent a lengthier replacement that is actually several distinct arguments. Processing of this type is sometimes called a ``substitution.'' In the ksh shell, an interesting form of substitution is the use of an alias, which is a brief way to refer to a longer command line. You create these alias names by using the alias command. See ``Aliasing'' later in the ``Description'' section, for more information regarding aliases. Substitutions other than aliasing require a metacharacter to help trigger substitution of the appropriate text. To indicate that you are making a reference to a variable, you precede the variable name with a dollar sign ($) 8 January 1992



ksh(1) ksh(1)
metacharacter. For aliases, a substitution is also performed, but with a notable difference in the request format: No metacharacter is required because the name being used as an alias must be placed at the beginning of a command line, and ksh always checks the command name at the beginning of a line to see if it is a previously defined alias. Unlike aliases, variable references can be placed at a point other than the beginning of a command line and still trigger a substitution. When ksh finds a properly positioned alias, it replaces it with the command name and command body that the alias was set to represent. If you had placed another command body after the alias at the beginning of the line, the new command body is added to the end of the command body (if any) that was stored for the alias. Note that the required positioning of command options ahead of other command arguments can become disturbed during the substitution process. You should plan the use of an alias to which you expect to append arguments so that you can define it in such a way that the enclosing command line that you supply extends the aliased command in a legal manner. For aliases that are associated with multiple commands, the last- referenced command is the only one that is subject to extension when the alias name is substituted. Another form of substitution applies to specially delimited subcommands: $((command)) Unlike substitutions of variables and aliases, which have static values that you assigned to them at some earlier time, command substitutions create replacement text by executing a command that generates output text. This text can reflect the system state precisely at the current moment. See ``Command Substitution'' later in the ``Description'' section, for more information about this type of substitution. Shell metacharacters are processed by the shell rather than by a command program. By processing shell metacharacters, the shell shifts the determination of the user interface away from individual command programs, and a more consistent command-line interface is easier to achieve. The benefit for you is that one shell-supported meta syntax can be applied to a number of command lines. After learning this metacharacter-based syntax, you can apply it very broadly to most of the commands you use. Step three: dispatching other programs. Completion of this step is closely related to the shell's ability to complete January 1992 9



ksh(1) ksh(1)
the previous step (deciphering of input). For example, if it cannot find a correctly entered command name (or Korn shell alias), the shell cuts this step short. In this case, the shell displays an error message instead of dispatching the program corresponding to a command. After the error message, the shell displays a new command prompt to initiate the next computer-human interaction. Suppose you included the ampersand metacharacter (&) on a command line. In step two, the shell detects its presence and removes it from the argument string that is passed to the command. In step three, the shell alters the way it dispatches the command program because of the metacharacter's presence. It uses a special invocation mode called ``background mode.'' When a command is invoked in background mode, the shell does not wait for it to complete before initiating a new computer-human interaction. Rather, the shell prompts immediately for a new command, and any work initiated by the last command is performed concurrently. Thus, there is an immediate transition from step three of the current computer-human interaction to step one of a new computer- human interaction. You must use a dedicated command to delete background-mode processes on those occasions when the background process does not self-terminate, or when you want to stop its execution prior to its completion. (See the description of kill in ``Built-in Commands,'' near the end of the ``Description'' section.) You can also bring a background job back to the foreground as described in ``Controlling Jobs Not in the Foreground,'' later in the ``Description'' section. Format of Command Lines The ksh program has certain restrictions on the ordering of elements of commands. These restrictions make their interpretation easier and their format more regular. The metacharacters are often oddball characters that would not normally be a part of the command you are entering. These characters are less likely to be confused with command options or arguments. Many of the specially interpreted metacharacters help you enter and run commands more efficiently, for example by avoiding lengthy typing. Once you learn to use the shell well, you will be able to enter shorter commands that nevertheless take advantage of very specialized processing or processing modes. For example, a terse notation is used to indicate that you want to direct the output of a command into a file, or to concurrently run one program with other programs already running. Another advantage is that these 10 January 1992



ksh(1) ksh(1)
metacharacter-triggered changes in processing are initiated in the same way for almost all commands. A disadvantage is that the oddball metacharacters create strange-looking command lines. Another disadvantage is that they may be difficult to memorize. When you want them to be treated literally, these metacharacters must be specially delimited, which also adds to the strange appearance of some command lines. This section describes the ksh-imposed rules for the structure of command lines. One restriction is that the command name must precede the command options and arguments. There are other requirements as well, such as the use of a command delimiter when you want to enter multiple commands on one line. Some of the shell metacharacters that you must use with care inside command lines are: ; & | $ ( ) < > ~ ? * [ ] newline space tab Not all of the functions of these metacharacters are described in this section. It makes sense to introduce some of them later, where they can be discussed along with some of the more advanced topics with which they are associated. (Additional metacharacter tokens are also described in ``Additional Korn Shell Metacharacters,'' near the end of the ``Description'' section.) Spaces and tabs are both referred to as ``white space,'' and one is as acceptable as the other when white space is required. White space is required between the command name and its (sometimes optional) command arguments: command-name white-space command-arg (Whether or not arguments are optional depends on the individual syntax requirements for particular commands.) White space is also used to delimit command arguments when you want to specify several of them: command-name [white-space command-arg]... For more information regarding the treatment of white space characters, see ``Argument Parsing,'' later in the ``Description'' section. Command separators are one type of shell metacharacter. They permit the specification of more than one command in the January 1992 11



ksh(1) ksh(1)
same line. The semicolon is interpreted as this type of metacharacter. The ampersand is also a command separator, with added functionality. It establishes background mode for the preceding command. When you establish background mode with an ampersand, do not include a semicolon as well. Because of this exclusivity, two syntax descriptions are needed to show the legal command syntaxes involving these command separators: command [; command]... command [& command]... With each command, you can specify an input and output redirection. Thus you can expand each occurrence of command as follows: command [redirect-in] [redirect-out] The value of the redirect-out element is the metacharacter > (greater-than sign) followed by a filename: > output-file The value of the redirect-in element is the metacharacter < (less-than sign) followed by a filename: < input-file Another form of redirection involves multiple commands that share an information flow, bypassing the need for intermediate files. Consider these two commands: who >/tmp/data grep tty1 </tmp/data The preceding sequence is equivalent to a pipe joining the two commands as a single processing request, as follows: who | grep tty1 The output of the first command (who) is channeled directly to the input of the second command (grep). The pipe metacharacter (a vertical bar) indicates this channeling of data between commands. You can extend the pipeline to channel the output of a second command to the input of a third command, and so forth: 12 January 1992



ksh(1) ksh(1)
command |command [|command]... While syntactically legal, file redirections inside a series of pipelined commands can conflict with the redirection established by the pipe, as in this example: command1 >file |command2 |command3 In this case, the input channeled to command2 is empty because the output of command1 is redirected to file first. See tee(1) if you need to channel a data stream to a file as well as into another command. Here is the the general format of a sensibly constructed pipeline, with no data redirection conflicts: command [<file1] [|command]... |command [>file2] [&] Note that a processing pipe such as this is equivalent to one processing job, particularly in terms of job control (as described next in ``Controlling Foreground Jobs'' and ``Controlling Jobs Not in the Foreground''). You cannot use command separators except at the end of a pipeline. By putting an ampersand at the end of a pipeline, you place in background mode all of the processing of the pipelined commands that precede the ampersand. If you use a semicolon instead of an ampersand, the pipelined commands are executed completely; after that, the command (or another pipeline) after the semicolon is executed. The processing request shown here illustrates how the pipe character causes a subsequent newline to be ignored (rather than treated as the end-of-command character). $ who | > grep console mikee console Jun 17 10:17 $ | For brevity of notation, the term command is used to represent any single- or multiple-command line, such as a pipeline, along with any file redirections. Controlling Foreground Jobs For jobs running in the foreground, a measure of control is available through certain control characters. To discontinue execution of a foreground command that is being processed, you can use the interrupt character. To discontinue processing of an interactive shell other than the login shell, you can use an end-of-file character (or January 1992 13



ksh(1) ksh(1)
the exit command). The interrupt character that stops a foreground command does not affect commands that are running in the background. For background processes, also known as ``jobs,'' other control provisions are required. These provisions are also known as ``job-control facilities.'' Rather than responding to control characters (such as interrupt characters), jobs respond to signals that are explicitly sent to them by discrete, signal-sending commands. Because there can be more than one background job running at the same time, you must also specify a command argument that can identify the job. To assist you, commands are available to display the numbers associated with jobs, including one called jobs. (See the next section that follows this one for related information.) Two ways of controlling jobs are necessary because there are two kinds of running jobs: foreground jobs and background jobs. Because foreground jobs execute one at a time, any command-based means of job control is awkward for controlling a foreground job. Instead you must use a key that generates an interrupt character to terminate a foreground job prematurely. From within the same interactive shell, you cannot cause a newly entered command to be examined while the prior foreground command is still running. (Normally you wait, until a new command prompt appears before you even begin to type another command.) Besides quitting a foreground job prematurely, you can also suspend its execution, normally by pressing CONTROL-Z. Later, you can resume its execution by using the job-control commands of ksh. To see what key combinations produce various control characters, enter the stty command with the -a option. In the output of stty, the caret (^) is used to represent the CONTROL key. By specifying other arguments, you change the mappings of keys to control characters (see stty(1)). When you suspend a job, ksh prints a short status line about the job before it issues the next prompt. Among other things, the status line reports the ksh-assigned job number (enclosed in brackets). By supplying that number as an argument to other built-in commands, such as bg and fg, you can further manipulate the state of the suspended job. For instance, you can resume its execution in the background by entering this command format: bg %job-number When you no longer want to enter new commands, you may want 14 January 1992



ksh(1) ksh(1)
to place a stopped job or a background job back in the foreground. To do so, use this command format: fg %job-number For more information about the fg command, see ``Built-in Commands,'' near the end of the ``Description'' section. For more information about monitoring both stopped jobs and jobs running in background mode, see the next section. Controlling Jobs Not in the Foreground To help you control and monitor running and stopped background jobs, ksh keeps track of the state of each job. This job-tracking service of ksh helps keep you informed about the progress of jobs and helps prevent you from losing track of running jobs. For example, if you try to exit from the shell while jobs are suspended, you receive this warning: You have stopped (running) jobs You can use the jobs command to see which jobs are suspended. If you try the exit command again, the shell does not warn you a second time, and the suspended jobs are terminated. Whenever a job becomes blocked and no further progress is possible, ksh informs you of its status. This information is made to appear just before a new shell prompt so that you can better distinguish it from the output of other commands. This particular job-tracking feature can be extended so that any background job that needs to display output similarly stops running, as described in the paragraphs later in this section that discuss the tostop argument for stty. Other customizations are also possible. For example, when you use the monitor option, each background job can be set to trigger another command upon its completion. Triggering commands requires setting a trap for the CHLD signal. (See the description of trap in ``Built-in Commands'' near the end of the ``Description'' section.) Using the ksh-assigned job number as an argument to certain built-in commands, you can place existing jobs in the foreground or background (restarting them in the process). You can determine the ksh-assigned job number in two ways: (1) You can use the built-in jobs command to obtain a numbered list of jobs. (2) You can notice the job number ksh assigns to a command line that is run in the background when ksh displays its status immediately after entry. The January 1992 15



ksh(1) ksh(1)
format of this status message is as follows: [jobno] process-id This line indicates that the command just entered is running in the background (asynchronously); has the process ID shown; and can be referenced as jobno for use along with the built-in, job control commands of ksh. To control jobs with commands that are not shell built-ins, you must use the process ID to refer to the process. The process ID is also reported by the process status command, ps, which is described in ps(1). When you use the built-in ksh commands for controlling jobs, you reference a job by using a job number, prefixed by the percent character (%). For instance, to place job number 1 in the foreground, enter fg %1 The argument %% or %+ can be used to refer to the most recent background job. The argument %- refers to the next- most-recent job. You can also reference a job by using a string that matches the command name you originally entered to begin the job. Thus, the following command restarts a suspended ed job, provided a suspended job whose name begins with the string ed is present: fg %ed Similarly, the following command format resumes any job whose original command line contained the string old-command-substring. fg %?old-command-substring The shell keeps track of the most recent job. In ksh messages about jobs and in the report displayed by the jobs command, the most recent job is prefixed with a plus sign (+) and the next-most-recent job is prefixed with a minus sign (-). The following processing request illustrates this point: $ sleep 525 & $ sleep 330 & $ sleep 250 & $ jobs 16 January 1992



ksh(1) ksh(1)
[3] + Running sleep 250 & [2] - Running sleep 330 & [1] Running sleep 525 & $ | The process running in the foreground has fairly exclusive access to input entered at the terminal. If a foreground command is underway, then the shell shares access to input typed at the terminal with the foreground command. By sharing access to input, the shell still has a chance to interpret certain control characters, such as the interrupt character, or to accept characters of the next command to be run (a type-ahead feature). However, a job running in the background cannot continue to run if it requires user input, because it does not have access to any of the data typed at the keyboard. Thus, when any of the background jobs requires user input, the shell stops the job. You can resume its execution by making it the foreground job and then supplying it with the data that it requires. To make it the foreground job, you must enter a command, so you will have to wait until any foreground job still underway completes, or you will have to interrupt it. Background jobs are normally allowed to send output to the terminal (or associated CommandShell window) without interference from ksh. However, this manner of operation can be disabled, so that ksh stops the execution of any job that needs to display a message. To establish the shell as a moderator for background jobs that are about to display output, enter stty tostop If you have used the monitor option (as described in the next section, ``Establishing Preference Settings,''), your interactive shell associates a job with each pipeline. A/UX provides another set of job-control commands that perform many of the same functions made available by the built-in commands of ksh. An advantage of using the discrete job-control commands such as kill, nice, and ps is that they are always available, even when you change to a shell other than ksh. These commands are described as separate entries elsewhere in the A/UX Command Reference. These discrete A/UX commands use a process ID number to identify jobs. However, the ksh-assigned job number is usually much shorter than the process ID number, and the built-in commands offer you greater simplicity. January 1992 17



ksh(1) ksh(1)
Establishing Preference Settings You can establish preference settings in several ways. For example, you can reduce the likelihood of overwriting an existing file with a new file of the same name by establishing the noclobber option, as follows: set -o noclobber To unset this preference, enter set +o noclobber If you are able to start the shell yourself, you can request the same preference on the command line, as follows: ksh -o noclobber Preferences such as noclobber are either on or off (set or unset, established or unestablished, and so on). You can determine the state of these preferences by using set with the -o option, as shown here: $ set -o Current option settings allexport off bgnice off emacs off errexit off gmacs off ignoreeof off interactive on keyword off markdirs off monitor on noexec off noglob off nounset off protected off restricted off trackall off verbose off vi on viraw on xtrace off $ | Other preferences, particularly those that can assume more states than on or off, can be stored in variables. To switch to a different command-input editor, you can make an assignment such as this one: 18 January 1992



ksh(1) ksh(1)
EDITOR=vi This particular variable assignment establishes vi as the command-input editor you wish to use. You could establish other editing styles, such as emacs and gmacs, in a similar way. Other preferences with many possible values are handled through commands built into ksh rather than through variables. For instance, you use the built-in commands uulimit and umask to establish operating limits (such as maximum file size) and default permissions for new files. For more details, see ``Built-in Commands'' near the end of the ``Description'' section. The ways of selecting preferences described so far do not make those settings permanent. They are in effect only as long as you use the shell into which you entered them. To retain these settings between uses of various login shells (after logging out and logging back in), you need to place them in a ``shell startup'' file. For ksh, the startup file is .profile. This is the file from which the shell obtains your initial preference settings whenever you log in to the system. Even if you have established a preference setting in a startup file or at the command prompt for the shell that is running, you can lose those settings if you invoke a subshell. To help establish preferences that persist not only across login shells, but also from shell to subshell, enter the preference in another startup file specified by the variable ENV, which is initially set to .kshrc in your home directory. A/UX offers another way of retaining preference settings from shell to subshell without entering them in a startup file, but you can use it only for preference settings that are held in variables. After you store a value in the variable, you reset or set its export attribute. The value of an exported variable in a subshell is the value it had as of the time it was last exported. However, this way of establishing a preference variable value does not persist across login sessions, and is subject to override by similar assignments placed in an ENV file. To set the export attribute of a variable, enter either one of the following commands: typeset -e variable export variable January 1992 19



ksh(1) ksh(1)
In a similar fashion, you can export aliases and functions to any ksh subshells, as the following commands illustrate: typeset -ef function-name alias -e alias-name Exported variables can affect commands you execute as well as subshells you invoke. Commands are also able to respond to settings contained in exported variables (sometimes called ``environmental variables''). Typically, however, commands ignore all but a few of the values that you export into the environment, unless the command is ksh itself. Typically, you export those values that at the very least affect a ksh subshell. TERM is an example of a variable that both commands and subshells regularly honor. The value of this variable also helps establish what type of terminal device you are using. The value of this variable helps A/UX programs look up the correct control sequences to use with particular terminals for various display functions, such as advancing the cursor location (see termcap(4) and terminfo(4)). Initially, TERM is set to a value identifying the console terminal as a Macintosh computer. However, during a CommandShell session in which you communicate with a host computer over a network, chances are slight that the host will understand this local setting for TERM, so another value should be used for the remote shell, such as vt100. You can temporarily export a preference variable value for the duration of one command. For instance, to ignore the currently exported value of TERM and to use vt100 instead, but only for the vi command, enter TERM=vt100 vi You can use the set command with the -k option to affect the way shell variable assignments are treated when interspersed with other command elements. (Also see the discussion of -k in ``Arguments,'' earlier in this manual page). For example, consider the variable assignments inside the following command block: echo var=b c ; set -k ; echo var=b c Because the first echo command is interpreted before the -k option takes effect, it generates this output: var=b c 20 January 1992



ksh(1) ksh(1)
Because the second echo command is interpreted after the -k option takes effect, it generates this output: c Use of this feature is strongly discouraged. This option may not be supported in future releases. You can use the discrete command printenv, or the built-in command typeset with the -x, option to find out the names and values for all exported variables. When invoked, ksh gets its environment variable settings either from the parent shell or from one of the log-in programs. It then passes the settings to any commands or subshells you invoke, unless you manually removed them from the environment first (by removing the export attribute). Here are some other variables with which you should be familiar: CDPATH Contains a list of search directories that are honored by the cd command. See the description of the cd command in ``Built-in Commands,'' near the end of the ``Description'' section. CMDSHELLPREFS Contains the name of a file in your home directory where CommandShell stores and reads your preferences. See CommandShell(1) for more information. EDITOR HISTFILE HISTSIZE Contain values that select the style of editor for command lines, select the file where previously entered commands are stored, and set the number of command lines subject to storage and recall, as described in the next section, ``Command Reentry.'' FINDER_EDITOR Contains the pathname for the editing application to be launched when you open a text file by way of the A/UX Finder. PATH Contains a list of command search directories. (See ``Command Execution'' later in the ``Description'' section.) PS1 Contains the string used as your primary command January 1992 21



ksh(1) ksh(1)
prompt. PS2 Contains the string used as your secondary command prompt for those occasions when you must enter a block of commands that spans more than one line. (See ``Using Repetition and Branching Constructs,'' later in the ``Description'' section, for related information.) MAIL MAILCHECK MAILPATH Contain values that help enable and customize electronic mail. See ``Other Built-in Variables,'' near the end of the ``Description'' section, for more information. TBMEMORY TBPATCHES TBRAM TBSYSTEM TBTRAP TBWARN Contain values that help configure system parameters that apply to the virtual Macintosh environment. See startmac(1) for information regarding these variables. Command Reentry The text corresponding to the most recent block of commands is saved in a history file. The value of the variable HISTSIZE determines how many lines of commands are saved; it is initially set to 128. The value of the variable HISTFILE selects the file where the saved commands are stored; it is initially set to $HOME/.sh_history. Subshells also have access to commands that were previously given from the parent shell, provided that you do not change the value of HISTFILE for the subshell. You can use the built-in command fc to select a previous line to edit and reuse. To display a list of recently performed commands, enter: fc -l This command produces a list of recently used commands, such as this one: 416 date 417 whoami 418 cd /tmp 419 ls -tC 420 cat lastfsck 22 January 1992



ksh(1) ksh(1)
421 cd 422 ls -tC 423 more today 424 rm today 425 fc -l To edit and reuse one of the commands from the history list, specify the line number as an argument to the fc command: fc line-number If you supply a string rather than a line number, the most recent command whose starting letters match the letters in the string is recalled for editing and reuse. You can also specify a range of old commands to be recalled for editing. Refer to ``Built-in Commands,'' later in the ``Description'' section, for a more complete description of the command options and arguments for fc. The edited command is printed and reexecuted when you leave the editor. The editor used is that specified by the value of FCEDIT, which is initially set to /bin/ed. You can also set the value of this variable to vi for full-screen editing, or you can set it to TextEditor for a mouse-and-menus style of editing. The ksh shell has its own built-in command-editing support as well. See ``Command-Line Editing Options,'' later in the ``Description'' section, and the sections that follow it. Frequently Used Built-in Commands This section provides a brief list showing some of the commands that are more fully described in ``Built-in Commands'' near the end of the ``Description'' section. You may want to familiarize yourself with the commands listed here sooner than any others. alias Creates pseudo commands that you can use as a shortcut for typing in much longer command lines. Also see ``Using ksh,'' earlier, and ``Aliasing,'' later in the ``Description'' section. bg fg jobs kill Control any running and suspended background jobs you have started. Also see ``Controlling Jobs Not in the Foreground,'' earlier in the ``Description'' section. January 1992 23



ksh(1) ksh(1)
cd Sets the current working directory to the directory specified as an argument. exit Exits ksh. pwd Displays the current working directory. ulimit Establishes the upper size limit for a file as one of the many limits that can be set. umask Establishes how file permissions are initially set for new files that you create. Command Execution The earlier sections in this manual page introduce the general functions of the shell and its commonly used features. The next series of topics provide a glimpse into the inner workings of the shell, including: processing that supports command execution, processing that can change the execution environment for a command based on metacharacters you placed in a command line, and processing that can change the value of various metacharacter-delimited command elements. If you enter a command name that matches one of the built-in commands, the command is executed as part of the current shell process. As such, it is not subject to the job-control commands that would affect an independent process. Next, the shell checks whether the command name matches one of the user-defined functions and evaluates the function's replacement, if necessary. A function is also executed as part of the current shell process, so it is also not subject to job control. For more detailed information about functions, refer to ``Functions'' near the end of the ``Description'' section. That section is generally useful for users who are also programmers. Then the shell determines if any alias substitutions must be made. Whether it is the result of an alias substitution or not, the command name can refer to an A/UX command, a Macintosh application, or a command script. Before this determination can be made, ksh must locate the executable file associated with the named command. So ksh performs a search for the command file. It searches for a file of the same name as the command entered. It looks in each of the search directories specified in the PATH variable. 24 January 1992



ksh(1) ksh(1)
The PATH variable contains a list of directories where commands are customarily located. Directory names are separated by colons (:). The default search setting for recent versions of A/UX is as follows: PATH=/bin:/usr/bin:/usr/ucb:/mac/bin:. When you use this specification, the final directory searched is the current directory. The current directory is represented by a period. Because the period appears in the last colon-separated field, the current directory is the last directory to be searched. For the PATH variable value, the current directory can also be represented by two or more adjacent colons, or by a colon at the beginning or end of the path list. The search process is not performed if the command name is specified with a leading slash (/) character. In such a case, ksh expects you to supply the absolute path that locates a file that can be executed, or a relative path that locates the executable file based upon the current working directory. Once the executable file is found, the format of the file helps distinguish whether it should be run as a shell script, a command, or a Macintosh application. The latter option allows you to launch Macintosh applications by name, provided that they reside on an A/UX file system in a directory that is listed in the definition of the PATH variable. Note, however, that if the name contains a space, you need to enclose the command name in quotation marks. (See ``Escape Characters,'' later in the ``Description'' section for related information.) To make the application easier to launch from a command line, you may want to rename the file so that it doesn't contain spaces: mv "MacDraw II" macdraw Launching Macintosh applications by name is about the same as using the launch command (described in launch(1)). This method supports the same -p (print) option described for launch: mac-application [-p] [app-document]... For a command to run successfully, ksh must be able to find an associated executable file. Successful execution also depends upon the execute permission for that file (which is interpreted according to the login account you used to log in). The often-misleading File not found error message is displayed if the file permissions do not permit you to run the command. January 1992 25



ksh(1) ksh(1)
If the result of the command search yields a file that is a command-containing shell script, a subshell is spawned to interpret the script as described in ``Command Scripts,'' later in the ``Description'' section. The processing steps described in this section represent the minimum processing that ksh performs to run a simple command such as: $ date Fri Jun 14 13:31:22 PDT 1991 $ | However, much more shell processing of command lines can optionally take place. Before you can master the command- line interface, you need to better understand how that optional processing is performed by the shell. To give you a more detailed understanding of the optional ksh processing, you should read the series of the sections that follow this one. Each subsection elaborates on one type of optional shell processing: ⊕ Subcommand Execution ⊕ Aliasing ⊕ Tilde Substitution ⊕ Command Substitution ⊕ Variable Substitution ⊕ Filename Generation ⊕ Argument Parsing ⊕ Input/Output Redirection ⊕ Escape Characters ⊕ Extra Initial Processing for a Login Shell ⊕ Extra Initial Processing for Subshells Subcommand Execution Parenthesized commands are executed by a subshell. Unlike a subshell that supports the running of command scripts, this subshell has access to nonexported variable values from the parent shell as well as exported ones. You can combine commands to be executed by a subshell with ordinary commands into a single processing request, in 26 January 1992



ksh(1) ksh(1)
formats such as these: [command command-separator]...(subcommand) (subcommand)[ command-separator command]... Because the subshell can be set to a different working directory, you can use it to help initiate commands that operate in two different directories, but are still part of a single command-line request. One possibility is shown in the following example, which copies a directory/file hierarchy from one location to another: cd fromdir; tar cf - . | (cd todir; tar xf -) Aliasing As described earlier, ksh performs a substitution when it encounters an alias name in the command-name portion of a command line. When declaring aliases with the alias command, you can use any nonspecial printable character as the first character of the alias name. The remaining characters must be the same as those for a valid identifier. (See ``Lexical Rules for Identifiers'' later in the ``Description'' section.) For syntactic information regarding the use of the alias command, see ``Built-in Commands'' later in the ``Description'' section. The replacement string for an alias is a command line. Such a string can contain one or more references to commands or executable shell scripts. If it includes multiple commands, command separators must delimit them as described in ``Format of Command Lines,'' earlier in the ``Description'' section. Generally, the command-name portion of the replacement value for an alias is not tested for additional aliases. However, if the last-entered character of the replacement value is a space, ksh makes any appropriate alias substitution for the first command name in the replacement value. You can use aliases to redefine the built-in commands, but you cannot use them to redefine the keywords described later in ``Using Repetition and Branching Constructs'' within the ``Description'' section. You can create, list, and export aliases with the alias command. You can remove aliases with the unalias command. Exported aliases remain in effect for subshells but do not January 1992 27



ksh(1) ksh(1)
persist across login sessions unless you enter them in the file .profile. (See ``Establishing Preference Settings'' within the ``Description'' section.) Aliases are frequently used as a shorthand for longer command pathnames. The tracking feature for aliases enhances this use. It helps avoid the processing overhead that is otherwise required to locate the associated command each time an alias is used. The search that is normally moderated by the list of directories stored in the PATH variable is not always necessary because the shell can remember the full pathname to the aliased command after its first use. When such a manner of operation is enabled for an alias, the alias becomes a tracked alias. All tracked aliases become subject to reresolution each time the PATH variable is reset. When you do so, a search will take place to determine the correct location of an aliased command when the (tracked) alias is next used. Once the location has been reestablished according to the new PATH setting, the tracked alias is once again able to inhibit further command searches. To treat all the aliases you subsequently define as tracked aliases, use ksh with the -h option as described in the ``Arguments'' section, earlier in this manual page. For an interactive shell that is already running, you can use the set command with the trackall argument to establish the same ksh preference. (See ``Establishing Preference Settings'' earlier in the ``Description'' section.) You can set the export attribute for an alias to indicate that it should also be passed to any ksh subshells you invoke. To set this attribute, use the alias command with the -x option. For more information about exported values and the export attribute, see ``Establishing Preference Settings,'' earlier. The following ``exported aliases'' are set, but you can unset or redefine them: autoload='typeset -fu' false='let 0' functions='typeset -f' hash='alias -t' history='fc -l' integer='typeset -i' nohup='nohup ' r='fc -e -' true=':' type='whence -v' 28 January 1992



ksh(1) ksh(1)
Tilde Substitution After performing alias substitution, ksh processes the command line for a type of substitution known as ``tilde substitution,'' so-named because the metacharacter that triggers it is the tilde ( ). When used as a discrete
~
command argument, or when placed at the beginning of a
pathname, the tilde is replaced with the full pathname to your home directory (the directory that becomes your default working directory when you log in). If the tilde precedes an argument that is a login name from /etc/passwd, then ksh substitutes the home directory of the login name specified. If no match is found, ksh leaves the tilde and any attached text unsubstituted, and treats them literally as command arguments. You use the tilde primarily to avoid some typing when you want to specify files in your home directory but your current working directory is set elsewhere. Using the tilde can also reduce typing when you are specifying the path to an executable command file located in your home directory. The syntax for a command request that makes use of tilde substitution for the command name is as follows: [login-name][/dir].../command arg...
~
The syntax for a command request that makes use of tilde substitution for a command argument is as follows: command [login-name][/dir]...[/file]
~
A tilde followed by a + or - is replaced by the value of the current working directory (PWD) or the old working directory (OLDPWD), respectively. In addition, tilde substitutions are performed if the tilde is placed at the beginning of the assignment value for a variable: variable= value
~
The tilde can also be placed elsewhere in the assignment value for a variable, as long as it is after a colon (:). For example, tilde substitutions may permit you to specify search directories for the PATH variable more succinctly, as in this example: $ PATH=/bin:/usr/bin:~:~/Tools: $ echo $PATH /bin:/usr/bin:/disk0/mikee:/disk0/mikee/Tools January 1992 29



ksh(1) ksh(1)
$ | Command Substitution After performing any tilde substitutions, ksh processes the command line for metacharacters that request another type of substitution. ``Command substitution'' permits you to enclose command lines inside other command lines. The enclosed commands are replaced with the output text they produce when they are run. Of course, any enclosed commands are run first. You delimit an enclosed command by placing it inside parentheses, and by placing a dollar sign in front of the open parenthesis: $(enclosed-command-line) If it occupies the position normally occupied by a command, the enclosed command must output a legal command. If it occupies the position normally occupied by a command argument, the enclosed command must output a legal argument for the enclosing command. You can use command substitution to avoid typing a long list of filenames, as in this example: tbl $(grep '^\.TS' * |cut -f1 -d: |sort -u) |nroff In this example, the enclosed command is as follows: grep '^\.TS' * |cut -f1 -d: |sort -u This enclosed command generates the arguments for the tbl (table-preprocessing) command. In this case it is a list of files in the current directory that contain at least one occurrence of the table-start instruction, .TS, located at the beginning of a line. (The function of the grep command is to find occurrences of strings in files and report them.) The cut command strips all but the first colon-delimited field from its input data. Because grep reports the names of files, a colon, and the line that contains the search string, cut outputs only filenames in this example. Those filenames are sorted into a list without any duplicates by the next pipelined command, sort -u. So when the enclosed commands are done executing, they produce as the arguments for tbl a list of files containing tbl instructions. The output of tbl is intended to be processed by a document- formatting program, such as nroff, so the enclosing command pipes tbl output as input to the nroff command. 30 January 1992



ksh(1) ksh(1)
In addition to the usual method of requesting command substitution just described, you can enclose a command substitution in grave accents: `command` When you use this (archaic) delimiter, the command between the grave accents goes through two rounds of processing for quotation mark metacharacters before the command is executed. (See ``Escape Characters,'' later.) Instead of specifying $(cat file ) you can use the following request, which is faster: $(<file) Most built-in commands that are not requested along with input/output redirection are executed in the same process as ksh when they are used as a command inside another command. Variable Substitution After performing command substitution, ksh processes the command line for variable substitution (also known as ``parameter substitution''). The dollar sign ($) metacharacter that introduces a variable name can be considered the trigger for variable substitution. The dollar sign and the variable name that follows it are replaced with the value of the variable. Here is the format: $variable Usually variable is composed in accordance with the rules for identifiers. This is the case in particular for all user-defined variables. (See ``Other Built-in Variables'' later in this section, for variables that are preestablished.) Another class of variables can be referenced in this format: $digit ${digit...} These variables are called ``positional parameters.'' Their primary use is to allow access to the command-line parameters from inside a user-programmed shell script. For more information about scripts, see ``Command Scripts,'' January 1992 31



ksh(1) ksh(1)
later in the ``Description'' section. For more information about variables and arrays, see ``Variables and Arrays,'' near the end of the ``Description'' section. Filename Generation After performing variable substitution, ksh processes the command line for metacharacters that request filename generation. Filename generation involves replacing a shorthand reference to a file with a more complete pathname or filename. Such a shorthand reference involves certain metacharacters, also referred to as ``wildcards.'' Often more than one argument is generated in place of a shorthand argument. This happens when several filenames or pathnames satisfy the wildcard criteria. If you use one or more wildcard metacharacters, ksh regards the word in which they appear as a shorthand notation to be expanded, as long as the word is not enclosed in single (') or double (") quotation marks. One of the metacharacters, or wildcards, that trigger this processing is the asterisk (*). Because variable substitution is performed before filename generation, the wildcard can be part of the text stored in a variable, as the following processing request shows: $ files=/.*rc $ echo $files /.cshrc /.kshrc $ | The same results are evident in the following commands, in which variable substitution plays no role. Also note that filename generation is suppressed by the double quotation marks. $ echo /.*rc /.cshrc /.kshrc $ echo "/.*rc" /.*rc $ | The ksh program sorts generated arguments alphabetically when multiple filenames are generated because of a request for filename generation. The output produced by echo in the following processing request comprises any files in the current directory that end with the suffix .out. Note that the output is sorted alphabetically. 32 January 1992



ksh(1) ksh(1)
$ echo *.out temp.out work.out $ | If ksh cannot generate any filenames based upon the wildcards in the argument you specify, then the argument is treated as a literal argument. Thus, if the current directory does not contain any files with a .out suffix, filename generation for the previous example would fail, producing this output: $ cd $ echo *.out *.out $ | The term ``pattern'' is used to refer to the wildcard along with the word in which it appears. So *.out can be thought of as a single search pattern. When used as the first character of a search pattern, such as *.out, the asterisk produces file matches for any filenames containing any number of characters of any value, that end with the characters .out. When used as the last character of a search pattern, such as memo*, the asterisk produces file matches for any filenames containing any number of characters of any value, that start with the letters memo. Wildcards other than the asterisk are more restrictive in terms of the matches they can produce. Particularly, they match only one character within a filename. You must use multiple occurrences of these other wildcards in the pattern in order to match a filename of more than one character. The question mark matches any one character of any value. Suppose you enter: ls ??? The output produced comprises all the filenames that contain exactly three characters. When question marks are used along with strings, as in memo?.out, the matched filenames must be the same length as the pattern. To form an even more restrictive wildcard, a wildcard that matches only certain characters in certain positions, a single character is not sufficient. For this kind of wildcard specification, a bracketed character list is used. Suppose you enter January 1992 33



ksh(1) ksh(1)
ls memo[123] The output produced comprises all the filenames that begin with memo and that end with either 1, 2, or 3. The following list describes the criteria established by each of the wildcard notations. Note that in this list, the brackets shown are supposed to be typed. (When the brackets appear in the normal text font, as is usually the case, they surround optional items.) * Matches zero or more characters of any value. ? Matches one occurrence of any character value at a particular location. [char...] [!char...] Match one occurrence of any one of the enclosed characters in a particular character position (first form). If the first character in the list is an exclamation mark (second form), a match is produced whenever any one letter other than char occurs at a particular character position. The placeholder char can also be specified as a three- character sequence representing a range (based upon ASCII ordering) of characters to be considered matches. This three-character sequence has the following format: startchar-endchar Thus [A-Z] matches one occurrence of any uppercase letter and [A-Za-z] matches any alphabetic character in either uppercase or lowercase format. To include a hyphen (-) as one of the list of possible character matches, make it the first or last character enclosed within the brackets. When the filenames you want ksh to generate must be discriminated from very similar filenames, you may need to use more than one pattern to generate the desired files. Multiple patterns are separated by a vertical bar (|), as shown in the following summary of compound pattern syntaxes. For the patterns in this list, the brackets should not be typed because they surround optional items. ?(pattern[|pattern]...) Matches zero or one occurrence of the patterns specified. 34 January 1992



ksh(1) ksh(1)
*(pattern[|pattern]...) Matches zero or more occurrences of the patterns specified. +(pattern[|pattern]...) Matches one or more occurrences of any pattern specified. @(pattern[|pattern]...) Matches exactly one of the patterns specified. !(pattern[|pattern]...) Matches all strings, except those matched by the patterns specified. Argument Parsing After performing filename generation, ksh processes the argument portion of the command line to determine the number of arguments, the extent of each, and the level of escapement, if any, that you requested to obtain the literal interpretation of metacharacters. The first two functions involve parsing of the command argument string into discrete arguments according to the presence of argument-separator metacharacters. The space or tab metacharacters in a command line are in turn affected by the third function, analyzing the level of escapement. Escapement is specified by paired quotation marks or the backslash character. These metacharacters can override the normal interpretation of spaces or tabs as argument separators, making them legitimate argument string characters (See ``Escape Characters'' later in the ``Description'' section.) Input/Output Redirection The ksh shell performs input and output redirections after it has substituted aliases, evaluated command substitutions, evaluated functions, generated filenames, and replaced variables in accordance with metacharacters and other preference settings that you supplied. You specify a redirection of input, output, or both by using the appropriate metacharacter notation. Unlike processes that involve substitution, the process of redirection does not require that you make changes to the elements of the command line that get passed to the command. Rather, you accomplish redirection by altering the processing environment with which the command interacts. Redirection requests are not propagated to the command they affect. The shell parses them and processes them by itself. For this reason, redirections can be intermixed with other January 1992 35



ksh(1) ksh(1)
command elements in any way: command arg... [redirect-in] [redirect-out] [redirect-in] [redirect-out] command arg... You specify the value of redirect-out as the metacharacter > (greater-than sign) followed by a filename: > output-file You specify the value of redirect-in as the metacharacter < (less-than sign) followed by a filename: < input-file Another form of redirection involves multiple commands that share an information flow, bypassing the need for intermediate files. Consider these two commands: who >/tmp/data grep tty1 </tmp/data The preceding sequence is equivalent to a pipe joining the two commands as a single processing request, as follows: who | grep tty1 The output of the first command (who) is channeled directly to the input of the second command (grep). The pipe metacharacter (a vertical bar) indicates this channeling of data between commands. You can extend the pipeline to channel the output of a second command to the input of a third command, and so forth: command |command [|command]... More discussion of input and output file redirection and command pipes is given earlier in ``Format of Command Lines.'' You can request that filename generation be performed for the filename portion of a redirection request by using the wildcards described earlier in ``Filename Generation.'' Filename generation produces a full reference to a filename or pathname, from a shorthand reference (or pattern) that you provide. Note, however, that the pattern is treated literally if honoring it would generate multiple filenames. 36 January 1992



ksh(1) ksh(1)
More often, a redirection metacharacter introduces the name of a file that you want to use as the source of input or the destination of output for a command. You can also specify another parameter in a redirection request, the channel parameter. A more technical term frequently used in place of channel is ``file descriptor.'' Replace channel with a digit between 0 and 9, where applicable. The following list shows all the redirection formats available. <file channel<file Establish file as the source of standard input (file descriptor 0) for the command line in which it appears. If channel is specified (as in the second form shown), it establishes file as the source of input for the channel specified. >file channel>file Direct the standard output (file descriptor 1) to file for the command in which it appears. If file does not exist, it is created. If file exists and the noclobber option is on, an error is generated; if file exists and the noclobber option is off, the file is truncated to zero length. If channel is specified (as in the second form shown), it establishes file as the destination for output written to the channel specified. >|file Directs the standard output (file descriptor 1) to file for the command in which it appears. This format differs from > because it overrides the noclobber option, which might produce an error message because a file by the same name already exists. >>file Directs the standard output (file descriptor 1) to file for the command in which it appears. If file exists, output is appended to it; otherwise, file is created. <>file Establishes file as the source of standard input and the destination of standard output. <<[-]word Establishes a range of lines as the source of standard input for the command line in which it appears. The range of lines starts with the next line and continues until a line is reached that consists of word alone, or that contains an end-of-file character. For this type January 1992 37



ksh(1) ksh(1)
of redirection, no parameter substitution, command substitution, or filename generation is performed on word. The resulting range of lines that is used as input is sometimes called a ``here-document.'' If any character of word appears in quotation marks, the input lines are treated literally. Otherwise, ksh performs parameter and command substitution on the input lines and the backslash (\) must precede certain metacharacters to ensure their literal interpretation as input data. Particularly, the following metacharacters are subject to interpretation unless escaped: backslash (\), dollar sign ($), and grave accent (`). If - is appended to <<, ksh strips all leading tabs from word and from the range of lines used as input. <&channel Establishes as the source for input the file (or device) currently associated with the file descriptor channel for the command in which it appears. >&channel Directs the standard output of a command to the file (or device) currently associated with the file descriptor channel for the command in which it appears. app-channel<&channel Establishes the file (or device) referenced by channel as the source of input read by the application from app-channel. app-channel>&channel Directs data sent by the application to app-channel to the file or device referenced by channel. <&- Closes the current source of standard input for a command. >&- Closes the current destination of standard output for a command. [channel]<&p Connects the output from the coprocess to the standard input or, if channel is supplied, to the file or device referenced by channel. [channel]>&p Connects the input of the coprocess to standard output or, if channel is supplied, to the file or device referenced by channel. 38 January 1992



ksh(1) ksh(1)
The order in which redirections are specified is significant. The shell evaluates redirections from left to right, making new associations based on the already established state. For example, the following line first associates file descriptor 1 with file fname; then it associates file descriptor 2 with the file currently associated with file descriptor 1 (that is, fname): command 1>fname 2>&1 If the order of redirections were reversed, as in command 2>&1 1>fname then the output directed to file descriptor 2 would be sent to the display rather than to the file fname. This is why: File descriptor 2 is first set to correspond to the file or device associated with the standard output, which by default is the display since no redirection preceded it; then the standard output (file descriptor 1) is associated with file fname. The result is that the standard output alone is redirected to the file fname, which could have been much more simply requested as follows: command >fname If a command is followed by an ampersand (&) and job control is not active, the default standard input for the command is the empty file /dev/null. Otherwise, the default execution environment for each new command is the same as the shell from which it is invoked in terms of its file descriptors. You can override those defaults by using any of the input/output redirections described in this section. Escape Characters To disable the special interpretation of metacharacters, such as spaces and dollar signs, you can insert other characters to cause the metacharacters to be interpreted literally. For example, any metacharacter preceded by a backslash is interpreted literally. By preceding a newline character with a backslash, you can allow a long command to take up more than one line, as follows: $ command argument1 argument2 argument3 \ argument4 $ | January 1992 39



ksh(1) ksh(1)
The conversion of a metacharacter to a nonspecial character that is treated literally is sometimes called ``escaping,'' and the characters that help accomplish this are called ``escape characters.'' A casual name for this (escapement) process is ``quoting.'' Normally, the shell begins parsing a new argument whenever it encounters a space character. To launch a program named SpiffWrite II, you could enter "SpiffWrite II" The double quotation marks suppress the interpretation of this line as a command named SpiffWrite with one command argument, II. When you do not want to supply a value for the first argument to a command, but you do want to supply values for the second and third arguments, you need to pass an empty string in the place of the first argument. Normally, an empty string would not result from the substitution of a variable that held nothing (or the evaluation of a subcommand that produced nothing). To ensure that they can be interpreted as empty arguments when empty, you can enclose such references within double quotation marks: paste "$file" /etc/passwd The following command will not wait to read from the standard input if filenames is empty: cat "`cat filenames`" By enclosing a sequence of characters that includes metacharacters inside single quotation marks, you prevent the usual interpretation of the metacharacters (effectively suppressing filename generation, variable substitution, and subcommand execution). However, a single quotation mark cannot be treated literally within text delimited in this way, unless it is preceded by a backslash. Note that the single quotation marks offer a different level of escapement than do the double quotation marks. For example, to treat two variable references and an intervening space as one argument, enclose them in double quotation marks: command "$variable1 $variable2" It is a mistake to enclose them in single quotation marks, unless you want to treat the entire string as one literal argument, as in this example: 40 January 1992



ksh(1) ksh(1)
$ echo '$variable1 $variable2' '$variable1 $variable2' $ | If you enclose a sequence of characters that includes metacharacters in double quotation marks, the metacharacters triggering variable and subcommand substitution are not escaped, enabling those functions for the delimited text. In particular, the following metacharacters are still treated specially when enclosed in double quotation marks: \ ` $ To cause these characters to be treated literally when enclosed in double quotation marks, precede each with a backslash. You can avoid the special interpretation of keywords and aliases by escaping any character of the keyword or alias name. The recognition of function names and built-in command names (listed later in ``Built-in Commands'') cannot be altered with escape characters. Extra Initial Processing for a Login Shell A login shell is invoked in a characteristic way by exec as part of the login process. The login shell helps trigger processing that should take place only once, immediately after you log in. This specially-timed processing permits preference settings stored in the startup file .profile to take effect each time you log in. The programs that manage the login process invoke ksh and pass its execution environment with the $0 positional parameter set to -ksh. Upon inspecting $0 and finding the leading hyphen, ksh reads commands from /etc/profile and then from either .profile in the current directory or $HOME/.profile, if either file exists. You can customize preference settings by using these startup files and by using exported and unexported attributes for variables. (For more information, see ``Establishing Preference Settings'' earlier, and in the next section.) Extra Initial Processing for Subshells For any invocation of ksh, including one for establishing a login shell, the command lines from the file (if any) stored in the variable ENV are read and executed. For this reason, preference settings established in the file referenced by ENV are also established for all invocations of ksh subshells, whereas preferences established from .profile are passed to subshells only if the settings are exported and January 1992 41



ksh(1) ksh(1)
only if they are not overridden by settings in the ENV file. (If ENV contains the appropriate metacharacters, ksh processes the replacement value for further substitutions. This process permits ENV to contain a reference to the built-in variable $HOME.) By default, home/.kshrc is the value stored in ENV, where home is the home directory for your user account. If ENV is not set or is empty, no initial commands are executed. Command-Line Editing Options This is the first of several sections about the editing of command lines. The following sections also deal with these topics: ⊕ The emacs Editing Mode ⊕ The vi Editing Mode ⊕ Commands for vi Input Mode ⊕ Cursor Movement Commands for vi Edit Mode ⊕ History Commands for vi Edit Mode ⊕ Text Editing Commands for vi Edit Mode ⊕ Other Commands for vi Edit Mode If you have already learned how to use a UNIX(Reg.)-style editor such as vi or ed, you can invoke those actual programs rather than using the imitations of them inside ksh. If you prefer to edit command lines by using a mouse- and-menus approach, you can even use TextEditor. To enter one of these editors, store the name of the desired editor in FCEDIT and then use the fc command as described earlier in ``Command Reentry.'' The editing systems that are described in this section are more tightly integrated with ksh, so they can offer even speedier access to a previously entered command. Because of their reference-style treatment here, you should already be comfortable with one or more of the editing programs as described in A/UX Text Editing Tools in order to be comfortable reading these sections. Be forewarned, however, that not all operations operate identically, particularly for the vi editing mode. When the command-line editing feature of ksh is active, you can edit the current command line and scroll up and down to inspect, edit, and reuse any of your previously entered 42 January 1992



ksh(1) ksh(1)
commands within the range of the history file. (See ``Command Reentry'' earlier, for more information about the history file.) You choose one style of command-line editing by assigning the variable VISUAL or the variable EDITOR one of these values: vi emacs gmacs These built-in editors are modeled after the the stand-alone editors that have the same names. For more introductory information, see the commercial books that describe the emacs and gmacs editors, or see A/UX Text Editing Tools for an introduction to the vi editor. Each of these built-in editors displays a recalled command line after the most recent command prompt. You can consider the area of the display affected as a one-line text window, the contents of which you can scroll to view other command lines in the command history file. You can set the width of the text window by using the variable COLUMNS. The text window width is set to 80 columns automatically whenever COLUMNS is unset. If the command line that you enter or that you recall from the history file exceeds the length of the text window, a special character is displayed at its boundary. This character provides a reference point (mark) for the characters horizontally scrolled into view as you move the cursor toward the end of a long command line. As the cursor reaches the text window boundaries, the text is horizontally scrolled so that the window continues to enclose the cursor. The mark changes, depending on where text has scrolled off the window. If text has scrolled off the end of the window, a > is displayed. If text has scrolled off the beginning of the window, a < is displayed. If text has scrolled off both the beginning and the ending of the window, a * is displayed. Command-Line Editing With vi When you use the vi style of editing, you flip between two modes of operation, one for entering text-editing commands and one for entering the text of a command line. The data entry mode is called ``input mode.'' The command entry mode, called ``edit mode,'' can be broken down further into modes such as character-insert and character-overwrite modes. January 1992 43



ksh(1) ksh(1)
Initially, you are placed in input mode so that you can enter the text of a command line. To begin editing text that has been entered, you switch to the edit mode by pressing ESCAPE, move the cursor over the character position that requires a correction (using motion commands in edit mode), and enter an edit command that invokes input mode once again, and then insert or overwrite text. When you are ready to run the command line, you press RETURN. You can do so from either input or edit mode. In the command tables in subsequent sections, the notation for control characters is caret ( ^ ) followed by the character. For example, ^f is the notation for CONTROL-F. You enter this key combination by pressing the F key while holding down the CONTROL key. You do not have to press the SHIFT key. Commands for vi Input Mode By default the editor is in input mode which lets you enter a command line that you wish to run. Within this mode the following character-commands are accepted. Erase Deletes previous character. (You define the erase character by using the stty command. This character is usually ^H or #.) ^D Terminates the shell. \ Causes the next erase, kill, or end-of-line character to be interpreted literally. Cursor Movement Commands for vi Edit Mode The following character sequences move the cursor in edit mode. For most of these commands, you can optionally provide a count parameter that proportionally increases the distance that the cursor travels. [count]l Moves the cursor forward (right) one character. [count]w Moves the cursor to the beginning of the next word. [count]W Moves the cursor to the beginning of the next word that follows a space. [count]e Moves the cursor to the end of the current word. [count]E Moves the cursor to the end of the current space- delimited word. [count]h Moves the cursor backward (left) one character. 44 January 1992



ksh(1) ksh(1)
[count]b Moves the cursor to the previous word. [count]B Moves the cursor to the preceding space-separated word. [count]fc Finds the next occurrence of character c in the current line. [count]Fc Finds the previous occurrence of character c in the current line. [count]tc Finds the next occurrence of c in the current line, then moves backward one character. [count]Tc Finds the previous occurrence of c in the current line, then moves forward one character. [count]; Repeats the last single-character find command (f, F, t, or T). [count], Reverses the last single-character find command. 0 Moves the cursor to the beginning of the line. ^ Moves the cursor to the first nonblank character in the line. $ Moves the cursor to the end of the line. % Moves the cursor to the balancing (, ), {, }, [, or ]. If the cursor is not on one of these characters, the remainder of the line is searched for the first occurrence of one of these characters. History Commands for vi Edit Mode The following character sequences display commands you entered previously as long as they fall within the range of your command history file: [count]k Displays the previous command each time k is entered. If a count parameter is supplied, the command that is count commands prior to the current one is displayed. [count]- Displays the previous command. Equivalent to k. [count]j Displays the next command each time j is entered. If a count parameter is supplied, the command that is count commands more recent than the current one is displayed (if such a command exists). [count]+ Displays the next command. Equivalent to j. [lineno]G January 1992 45



ksh(1) ksh(1)
Displays the command numbered lineno. You can obtain the line numbers associated with commands by entering fc -l. The default is the least recent history command. /[pattern] Searches backward through the history file for a previous command containing pattern. You indicate the end of the pattern by pressing RETURN (or by generating a newline). If you do not specify a pattern, the most recently specified pattern will be used. ?[pattern] Searches forward through the history file for a previous command containing pattern, as a counterpart to /. n Searches forward for the next match of the last pattern specified by a / or ? command. N Searches backward for the next match of the last pattern specified by a / or ? command. Text Edit Commands for vi Edit Mode You can use these commands to modify the currently displayed line. To use these commands, you either switch from edit mode to input mode and type new characters into a line; or you remain in edit mode and directly change a specific amount of text. In the latter case you can continue supplying other edit-mode commands. In the former case, you cannot access edit- mode commands again until you leave input mode. a Enters input mode. New text is entered after the current character. A Enters input mode. New text is entered after the last character of the current line. Equivalent to the command $a. [count]cmotion c[count]motion Enter input mode after marking for deletion the string starting with the current character and ending with the character that is count units away in the direction and units given by motion. If motion is c, the entire line is deleted and you enter input mode. C Enters input mode after marking the current line for deletion. S Enters input mode after deleting the current line; equivalent to the command cc. D Enters input mode after deleting the string starting with the current character and continuing to the end of the line. Equivalent to the command d$. [count]dmotion 46 January 1992



ksh(1) ksh(1)
d[count]motion Delete from the current character to the character that is count units away in the direction and units given by motion. If motion is d, the entire line is deleted. i Enters input mode. New text is inserted before the current character. I Enters input mode. New text is inserted at the beginning of the current line. Equivalent to the command ^i. [count]P Inserts the contents of the deletion buffer before the cursor. [count]p Inserts the contents of the deletion buffer after the cursor. R Enters input mode. New text replaces existing text as the cursor advances over the old text. rc Replaces the current character with c, while remaining in command mode. [count]x Deletes the current character. [count]X Deletes the preceding character. [count]. Repeats the previous text-modification command, replacing the previously supplied count with count. Converts the case of the current character and
~
advances the cursor.
[word-number]_ Enters input mode after pasting a word from the most recently executed command into the current command line. The particular word inserted depends on the value of word-number. If this parameter is omitted, the last word of the previous command line is inserted. Otherwise, word-number selects the word to be inserted in an ordinal manner. * Attempts filename generation based on the current January 1992 47



ksh(1) ksh(1)
word. Filenames that begin with the same letters as the current word are generated. If no match is found, a beep is generated. Otherwise, the word is replaced by the matched filename and you enter input mode. \ Attempts pathname completion. Replaces the current word with the longest common prefix of all filenames that begin with the same letters as the current word. If the match is unique and the match is a directory, a slash (/) is appended. If the match is unique and the match is a file, a space is appended. Other Commands for vi Edit Mode [count]ymotion y[count]motion Copy (``yank'') text from the current character to the character selected by motion and put it into the deletion buffer. The text and cursor are unchanged. Y Copies (``yanks'') text from the current position to the end of the line and puts it in the deletion buffer. Equivalent to y$. u Undoes the last text-modification command. U Undoes all the text-modification commands performed on the line. [count]v Displays this command into the input buffer. fc -e ${VISUAL:-${EDITOR:-vi}} count If count is omitted, the current line is used. ^L Inserts a line feed and redisplays the current line if you are in edit mode. Otherwise, this command is treated literally. ^J Executes the current line, regardless of mode. ^M Executes the current line, regardless of mode. # Inserts a number sign (#) before the line and then sends the line, converting it into a shell comment. Use this command to insert the current line into the history file without executing it. = Generates a lists of filenames that begin with the same letters as the current word. @lettS
e
e
r
arches for an alias by the name _letter. (Note that an underscore is prepended to the letter.) If an alias of this name is defined, its value is displayed. 48 January 1992



ksh(1) ksh(1)
The emacs and gmacs Editing Mode You enter the emacs (or gmacs) editing mode by using the emacs (or gmacs) setting for either the variable EDITOR or the variable VISUAL. The only difference between emacs and gmacs modes is the way they handle CONTROL-T: The emacs mode transposes the current character with the next character, whereas gmacs mode transposes the two previous characters. To edit lines, move the cursor to the point needing correction and then insert or delete characters or words as needed. All edit commands operate from any place on the line (not just at the beginning). All of the editing commands are control characters or escape sequences. In the command table that follows, the notation for control characters is a caret (^) followed by the character. For example, ^F is the notation for CONTROL-F. The SHIFT key is not pressed. (The notation ^? indicates DELETE.) The notation for escape sequences is M- followed by a character. For example, you enter M-f (pronounced ``meta f'') by pressing ESCAPE (ASCII 033) followed by the F key. The character case is significant; M-F is not the same as M-f, so in this case you do not press SHIFT. ^F Moves the cursor forward (right) one character. M-f Moves the cursor forward one word. (The editor considers a word to be a string of characters consisting only of letters, digits, and underscores.) ^B Moves the cursor backward (left) one character. M-b Moves the cursor backward one word. ^A Moves the cursor to the beginning of the line. ^E Moves the cursor to the end of the line. ^]char Moves the cursor to the first occurrence of the letter char on the current line. ^X^X Interchanges the cursor and mark. erase Deletes the previous character. (You define the erase character by using the stty command. This character is usually CONTROL-H or #.) ^D Deletes the current character. M-d Deletes current word. M-^H Deletes the previous word. (Pronounced ``meta backspace''.) M-h Deletes the previous word. M-^? Deletes the previous word. (Pronounced ``meta delete''.) If your interrupt character is ^? (DELETE, the default), this command will not work. ^T Transposes the current character with next character in emacs mode. Transposes the two previous characters in January 1992 49



ksh(1) ksh(1)
gmacs mode. ^C Capitalizes the current character. M-c Capitalizes the current word. M-l Changes the current word to lowercase. ^K Deletes all characters from the cursor to the end of the line. If given a parameter of 0, it deletes all characters from the beginning of the line to the cursor. ^W Deletes all characters from the cursor to the mark. M-p Pushes the region from the cursor to the mark on the stack. kill Deletes the entire current line. (You define the kill character by using the stty command. This character is usually CONTROL-G or @.) If you use two kill characters in succession, all subsequent kill characters will cause the generation of a line feed (useful when you are using paper terminals). ^Y Pastes the last-yanked text to the line. ^L Inserts a line feed and prints the current line. ^@ Sets the mark. M-space Sets the mark. (Pronounced ``meta space''.) ^J Executes the current line. ^M Executes the current line. eof Produces the end-of-file character, normally CONTROL-D. This command terminates the shell if the current command line is empty except for the end-of-file character. ^P Displays the command previous to the current one. Each time CONTROL-P is entered, the command prior to the one just fetched is displayed. M-< Displays the least recent (oldest) history line. M-> Displays the most recent (youngest) history line. ^N Displays the next-most-recent command. As long as more recent ones exist, each time CONTROL-N is entered, the next command in a previous sequence of commands is displayed. ^Rstring Searches backward for a previous command line containing string. If a parameter of 0 is given, the search is forward. The string is terminated by a return or newline character. If string is preceded by a caret (^), the matched line must begin with string. If string is omitted, the next command line containing the most recently specified string is accessed. In this case, a parameter of 0 reverses the direction of the search. ^O Executes the current line and fetches the next line relative to the current line from the history file. 50 January 1992



ksh(1) ksh(1)
M-digits Defines the numeric parameter; the digits are taken as a parameter to the next command. The commands that accept a parameter are ., ^F, ^B, erase, ^D, ^K, ^R, ^P, ^N, M-., M-_, M-b, M-c, M-d, M-f, M-h, and M-^H. M-letter Searches the alias list for an alias by the name _letter.(Note that an underscore prefix is added.) If an alias of this name is defined, its value is inserted on the input queue. The letter must not conflict with one of the metafunctions described in this list (so do not use the letters f, b, d, p, l, c, h). M-. Inserts the last word of the previous command into the current line. If preceded by a numeric parameter, the value of this parameter determines which word to insert instead of the last word. M-_ Inserts the last word of the previous command into the current line. Same as M-.. M-* Attempts filename generation based on the current word. Filenames that begin with the same letters as the current word are generated. M-ESCAPE Attempts filename completion. Replaces the current word with the longest common prefix of all filenames that begin with the same letters as the current word. If the match is unique, a slash (/) is appended if the file is a directory and a space is appended if the file is not a directory. M-= Lists all files that begin with the same letters as the current word. ^U Multiplies the parameter of next command by 4. \ Causes the next character to be interpreted literally. This character allows editing characters and your erase, kill, and interrupt characters to be entered in a command line or a search string. ^V Displays the version number for the shell. Command Scripts Command scripts are files containing a number of command lines that are run as one batch. The same command-line user interface that you use for normal command programs is also used to invoke scripts. You can run a file containing commands by supplying the name of the file as the command in a command line. As described earlier in the section ``Using ksh,'' a shell performs a search for the file corresponding to each command. The order of this search is dictated by the list of directories stored in the PATH variable. If the file is a shell script containing legal command lines, a subshell is spawned to interpret it. In the January 1992 51



ksh(1) ksh(1)
subshell, only ``exported'' aliases, functions, and variables retain the values they had in the parent shell. To make your script programs as easy to run as A/UX commands, you need to locate them in one of the directories specified by PATH and extend permission to a range of users (or just yourself) to execute the script file. See chmod(1) for information about permission attributes for a file. As an alternative to treating the shell script just like an A/UX command program, you can execute it by submitting the file as the input for ksh in one of these formats: ksh shell-script-file cat shell-script-file|ksh To execute a script this way, you need read permission, but not execute permission. Note that any setuid and setgid file attributes are ignored. (These attributes are described in chmod(1).) When you specify a shell script as an argument to ksh, ksh performs a PATH-moderated search to discover where the named shell script resides. This search is exactly like the search for scripts executed like commands. When executed like a command, a script file for which you have set the setuid permissions, setgid permissions, or both is executed in a special way. The shell executes an agent that sets up an altered execution environment for use when running the script. This special subshell obtains its startup settings from /etc/suid_profile. Since ksh reads at least one line at a time, new aliases do not affect subsequent commands on the same line, but affect only subsequent lines. For example, if you have two or more simple or compound commands on a single line, such as this: alias bo=didley; bo ksh reads all of the commands on the line before executing them. Therefore, bo is not equivalent to didley because bo does not follow the alias command line. To add flexibility to shell scripts, traditional programming constructs are included. For example, you can establish a block of commands that is run only when a conditional test evaluates to true (such as whether a file exists), or when the test evaluates to false. Certain keywords help you indicate the scope of conditional blocks of commands. The keywords that specify conditional blocks of commands are if, elif, else, and fi. 52 January 1992



ksh(1) ksh(1)
Other keywords define blocks of commands that can be repeated a number of times. Each time a repeatable block of commands is executed, a test is performed to see if another iteration of the loop should be performed. For example, you could use the program segment shown here to process each file in a group of files in the same way: for file in chap1 chap2 chap3 do pr $file | lpr touch -a $file done Use of Comments An important part of programming is documenting the components of the program. Comments help anyone using the shell script understand the job of each program component. The # metacharacter tells ksh to ignore the remaining text on a line, treating it as a comment rather than a command line. Use comments throughout a lengthy shell script. Often they appear before a block of commands that has a common processing focus: # Was a valid filename was offered? # If not, report the error and exit. if [[ ! -f $file ]] then ... fi Specialized Command-Line Processing for Scripts When a script is invoked from the command line, the subshell that runs on its behalf is initialized to reflect the current state of the parent shell and the state of the command line. For example, any parent shell variables with the export attribute set are also initialized in the subshell. Furthermore, the command-line arguments given after the script filename are the source of assignment values for the positional variables of the subshell. The following example illustrates how command elements are mapped to positional variables: script-name earth wind fire water ↑ ↑ ↑ ↑ ↑ $0 $1 $2 $3 $4 January 1992 53



ksh(1) ksh(1)
This processing can be affected by preference settings for the argument-separator character, by command options for ksh (see the description of the -f and -k options in ``Arguments,'' earlier), by filename generation (see ``Filename Generation,'' earlier), and by escape characters (see ``Argument Parsing'' and ``Escape Characters,'' earlier). You can change the argument-separator character to something other than the default space and tab. To change the argument separator character, assign the desired separator to the IFS variable for the interactive shell you use to invoke the script. To refer to the script arguments beyond the ninth one, use this format for referring to the variable: ${digit...} Here is a simple script that displays the first two command-line arguments given to it: echo $2 $1 If you placed the preceding command in a file called swapargs and established execute permission for the file, you could duplicate the results of the following command line: $ swapargs one two two one $ | The special built-in variables $* and $@, when not enclosed by quotation characters, cause identical substitutions to occur. They are replaced with the text of each of the positional variables, with space characters (or the character stored in the IFS variable) inserted between each variable. When the same references are enclosed within quotation characters, the replacement values are subject to different interpretation if ksh parses arguments on them again. (See ``Argument Parsing,'' earlier.) If you want to obtain the same positional variable assignments after a second argument-parsing process, use "$@" to refer to the positional parameters of the subshell. This variable ensures that ``escaped'' spaces that were originally part of discrete arguments remain a part of those arguments, and thereby results in a faithful restoration of the number and 54 January 1992



ksh(1) ksh(1)
composition of positional variables in subshells to a subshell. Besides allowing the shell to assign positional variables (described in ``Argument Parsing,'' earlier), you can set the positional variables yourself by using the built-in set command. (See ``Built-in Commands'' later in this section.) Using Repetition and Branching Constructs While control constructions such as conditional blocks and loops are mostly used in scripts, you can also use them in command lines. If you structure them normally, they will span more than one line. To provide you with an indication that the command entry is not complete, ksh switches to a different prompt temporarily. You can change this secondary prompt by using the PS2 variable. The usual interpretation of a newline signal is temporarily abandoned when you have entered one of the control keywords but not an associated terminating keyword. This signal permits you to enter any number of lines before you terminate the control construction by using the appropriate keyword (done, esac, or fi for loops, case structures, and conditional command blocks, respectively). For the line in which the terminating keyword is entered, it indicates the end-of-line character received is interpreted normally: the end of the command-block entry and the beginning of its execution. The following example is a repeat of an earlier one. Shown here are the prompts that would appear before each of the commands or keywords during interactive operation: $ for file in chap1 chap2 chap3 > do > pr $file | lpr > touch -a $file > done $ | Once all of the command blocks have been closed (all nested loop or branch structures ended with the appropriate terminating keyword), ksh checks the command blocks for errors. If there are none, the shell runs the individual commands in each of the blocks one or more times, depending on the constructions used and the conditional expressions that govern their execution. Usually blocks of commands are entered into a script, which is a file that contains command lines. (See ``Command Scripts,'' earlier.) This permits them to be easily recalled without a lot of typing. January 1992 55



ksh(1) ksh(1)
A control structure must contain a conditional expression that yields a Boolean value. Conditional expressions are evaluated upon each iteration of a loop so that the shell can determine when to exit the loop (for instance, after a certain number of iterations). Likewise, conditional expressions control whether a conditional command block executes or is skipped (and optionally whether an alternative, else-introduced command block executes). How are these Boolean values obtained? Each A/UX command returns an exit status value that is habitually not displayed as part of the output text for a command. Nevertheless, this exit value is communicated to the shell that dispatched the command and is accessed through the $? variable. If multiple commands are dispatched together as part of a pipe or as part of a sequence of commands separated with ampersand or semicolon metacharacters, the exit status remembered is the exit status of the last command in the series. Control Structure Syntax You can change the normally sequential flow of shell execution from one command line to the next by using the keywords described in this section. You use the placeholder list to represent one or more commands that are executed under the control of a loop or conditional construction. You can include an arbitrary number of newlines instead of semicolons to delimit commands in list. The notation for identifier [in arg...] ;do list ;done is equivalent to for identifier [in arg...] do list done Here, the argument identifier is used to represent a name chosen by you and appearing in the some variations of the for loop. (See also ``Lexical Rules for Identifiers,'' later.) Because the argument list is used to represent any sequence of commands, it can also appear at locations where a Boolean result is required. In such cases, the real use of the commands in the list is to generate a Boolean result that in 56 January 1992



ksh(1) ksh(1)
turn dictates whether another block of commands should be run or should be skipped. Most of the time, the built-in command test (or an equivalent form of this command) is run as described later in the section ``Built-in Commands.'' The true or false result generated is based upon the exit value of the last command in the list. A true result is generated if the last command has a 0 exit value. A false result is generated otherwise. Only the exit values of command lists that are located immediately after one of the keywords if, elif, and while is subject to this manner of interpretation by ksh. Note that the command blocks whose execution is affected are also notated with list in the syntax descriptions that follow. for identifier [in arg [white-space arg]...]; do list ;done The commands between the do and done (represented notationally as list) keywords are repeated as many times as there are white-space separated arguments between in and do. Each time through that set of commands, the variable identifier is assigned the value of one of the arguments represented here as arg values. The commands in list can contain references to $identifier, which will contain a value equal to the nth arg value upon the nth iteration of the loop. If no arguments are specified between in and do, the for command executes the commands in list once for each positional parameter that is set. (See ``Specialized Command-Line Processing for Scripts,'' earlier.) Iteration ends when the positional parameters have been exhausted. select identifier [in arg ... ] ;do list ;done Writes to standard error channel (file descriptor 2) each arg value given that is preceded by a number. If in arg... is omitted, then the positional parameters are used instead. (See ``Specialized Command-Line Processing for Scripts,'' earlier.) The PS3 prompt is printed, and a line is read from the standard input. If this line consists of a number referencing one of the enumerated arg values, then the value of the variable identifier is set to the corresponding arg value. If the input line received is empty, the selection list is printed again. If the input value received is out of bounds, the variable identifier is set to an empty string. Whether in bounds or not, the input line received is saved in the variable REPLY. The commands in list are executed for each selection until a break character or an end-of-file character is received. January 1992 57



ksh(1) ksh(1)
case word in [pattern [ | pattern] ... ) list ;; ] ... esac Executes the command list associated with the first pattern that matches word. The form of pattern is the same as that used for filename generation. (See ``Filename Generation,'' earlier.) if list ;then list [elif list ;then list] ... [;else list] ;fi Executes the command list following if and, if a 0 exit status is returned, the command list following the first then command. Otherwise, a command list following any elif is executed and, if a 0 exit status is returned, executes the command list following the associated then is executed. Furthermore, when the first command list following an if command returns a nonzero exit status, any command list following an else command is executed. If the test conditions do not permit any command lists that follow either an else or a then command to be executed, then the if command returns a 0 exit status. while list ;do list ;done until list ;do list ;done Repeatedly execute both command lists until the first command list returns a value that terminates the loop. For a while loop, the iteration ceases when a nonzero exit value is returned. For an until loop, the iteration ceases when a 0 exit value is returned. If no commands in the list following do are executed, then the while and until commands return a 0 exit status; until can be used in place of while as a negation of the loop-termination test. (list) Executes list in a separate shell environment. Note that if two adjacent open parentheses are needed for nesting shells, you must insert a space between them to avoid producing a request for arithmetic evaluation as described in the next section. { list;} Executes the command block denoted by list. Note that { represents keyword and is not recognized unless it occurs at the beginning of a line or after a semicolon. [[expression]] Evaluates expression and returns a 0 exit status when expression is a test that evaluates as true. This command replaces the test command of previous shell versions. (See ``Conditional Expressions,'' later.) function identifier { list;} identifier() { list;} 58 January 1992



ksh(1) ksh(1)
Define a function that can then be referenced by the identifier supplied. Upon reference, the command list provided between { and } is executed. (See ``Functions,'' later.) time pipeline The commands in pipeline are executed, and the elapsed time, as well as the user and system time, are printed on standard error. The following keywords are recognized only when they occur at the beginning of a line or after a semicolon: if then else elif fi case esac for do while until done { } function select time Arithmetic Evaluation Use the following format to request arithmetic operations: ((variable=arithmetic-expression)) This format is equivalent to let "variable=arithmetic-expression" You can use arithmetic expressions to keep track of the number of loop iterations, as in this example: max=7 count=0 while [ $count -lt $max ] do ((count=$count + 1)) ... done You can use arithmetic expressions in two other ways. They can appear in an indexing expression that references an element in an array, such as student[$count+1] You can also use them in a let command, which you can use to initialize variables: let count=$tests*students Evaluations are performed by means of long arithmetic. Constants are expressed in one of the following formats: January 1992 59



ksh(1) ksh(1)
decimal-digit... [base#]digits-n-letters... In the first format, a decimal value (base 10) is assumed. In the second format, the base is given by base. It must be a decimal number between 2 and 36, and digits-n-letters specifies a number in that base. The rules of syntax, precedence, and associativity that apply to expressions in the C language apply here as well. All of the integral operators other than ++, --, ?:, and , are supported. You can reference variables by name within an arithmetic expression without using the parameter substitution syntax. When you reference a variable, its value is evaluated as an arithmetic expression. Because many of the arithmetic operators also function as metacharacters, you must suppress their metacharacter interpretation, often by placing them in question marks. An alternative form of the let command is provided to eliminate their interpretation as metacharacters. This alternative format uses opening and closing double parentheses to replace let, as described at the beginning of this section. Conditional Expressions A conditional expression controls the flow of execution through and around blocks of commands bounded by keywords such as those described earlier in ``Using Repetition and Branching Constructs.'' Many times, a test command will be included that generates a Boolean result. You can use the following test-command format. (In this syntax format, brackets are enterable characters - they do not enclose optional elements.) if [[ test-argument...]] Another (archaic) way to introduce these options and arguments is after the keyword test: if test test-argument... You can combine several Boolean conditions by replacing test-argument with a number of binary and unary tests joined together by using logical operations such as logical AND (&&) and logical OR (||). You can invert the Boolean value produced by a test argument by preceding it with a negation operator (!). 60 January 1992



ksh(1) ksh(1)
Argument parsing takes place, consuming the white-space that separates arguments, except when you use escape characters to preserve the literal interpretation of spaces. Filename generation is not performed even when test arguments are represented by file as shown in the following list. The following primitives are available for use as test arguments: -a file True if file exists. -b file True if file exists and is a block special file. -c file True if file exists and is a character special file. -d file True if file exists and is a directory. -f file True if file exists and is an ordinary file. -g file True if file exists and has its setgid bit set. -k file True if file exists and has its sticky bit set. -n string True if the length of string is nonzero. -o option True if option is on. -p file True if file exists and is a First-In-First-Out (FIFO) special file or a pipe. -r file True if file exists and is readable by the current process. -s file True if file exists and its size is greater than 0. -t n True if file descriptor number n is open and associated with a terminal device. -u file True if file exists and has its setuid bit set. January 1992 61



ksh(1) ksh(1)
-w file True if file exists and is writable by the current process. -x file True if file exists and is executable by the current process. If file exists and is a directory, the current process has permission to search in the directory. -z string True if string is an empty string. -L file True if file exists and is a symbolic link. -O file True if file exists and is owned by the effective user ID of this process. -G file True if file exists and its group matches the effective group ID of this process. -S file True if file exists and is a socket. file1 -nt file2 True if file1 exists and is newer than file2. file1 -ot file2 True if file1 exists and is older than file2. file1 -ef file2 True if file1 and file2 exist and refer to the same file. string1 = string2 True if the strings match one another. string1 != string2 True if the strings do not match one another. string1 < string2 True if string1 comes before string2 based on the ASCII value of their characters. string1 > string2 True if string1 comes after string2 based on the ASCII value of their characters. exp1 -eq exp2 62 January 1992



ksh(1) ksh(1)
True if exp1 is equal to exp2. exp1 -ne exp2 True if exp1 is not equal to exp2. exp1 -lt exp2 True if exp1 is less than exp2. exp1 -gt exp2 True if exp1 is greater than exp2. exp1 -le exp2 True if exp1 is less than or equal to exp2. exp1 -ge exp2 True if exp1 is greater than or equal to exp2. You can construct compound expressions from these primitives, listed in decreasing order of precedence: (expression) True if expression is true. Used to group expressions. ! expression True if expression is false. expression1 && expression2 True if expression1 and expression2 are both true. expression1 || expression2 True if either expression1 or expression2 is true. Additional Korn Shell Metacharacters The Korn shell treats several two-character tokens as if they were a single metacharacter. The token |& causes asynchronous execution of the preceding command or pipeline as does the ampersand alone, but with a rather unusual redirection of input and output. The input and output are both redirected to the (parent) shell process from which the command was dispatched. To read and write lines of the input so created, you execute the read and print commands with the -p option from the parent shell. These commands are described later in ``Built-in Commands.'' Only one command redirected in this fashion can be active at any given time. The tokens && and || join two commands together, conditionally performing the command that follows them. Here is the format of commands joined this way: January 1992 63



ksh(1) ksh(1)
command && conditionally-run-command command || conditionally-run-command When conditionally-run-command follows &&, it is executed only if the preceding command exits with a zero exit status, which is usually an indication of successful command completion. When conditionally-run-command follows the || token, it is executed only if the preceding command exits with a nonzero exit status. The precedence of the metacharacter operators is given in the following list. Those in the first line are given higher precedence than those in the second line. && || ; & |& Variables and Arrays Variables do not have to be declared before they are used. Usually the variable name is composed in accordance with the rules for identifiers. At least this is the case for all user-defined variables. For certain built-in variables, names have been previously established that do not meet the criteria for identifiers. Here are some examples: $* $@ $# $? $- $$ $! A Korn shell variable has several other attributes besides its associated value. Using the typeset command, you can set some of these attributes. For more technical information regarding typeset, see ``Built-in Commands,'' later. Variables with the export attribute set are passed along to subshells and commands as part of their inherited execution environment. The passed variable values, and the passed attribute values (such as export), are those in effect at the time the exported attribute is made active. 64 January 1992



ksh(1) ksh(1)
Variables can be assigned the string or number value denoted as value, as follows: name=value [name=value]... To make an assignment by using an arithmetic expression, use one line per assignment in the following format: ((name=expression)) For variables with the integer attribute set, arithmetic evaluation is performed on the assignment even if the double open and close parentheses are omitted. By declaring count as an integer with the format typeset -i count the result you obtain from the following commands becomes the same result: count="3 + 2" ((count=3 + 2)) One way to establish values for positional variables is to use the set command. (See the description of set in ``Built-in Commands,'' later.) When you are writing shell script programs, the positional variables are automatically set by the invoking shell to support the passing of the command-line arguments for use inside the program. In such a case, $0 is set to the script name. See ``Specialized Command-Line Processing for Scripts,'' earlier. The shell supports one-dimensional arrays. An element of an array variable is referenced by a subscript. A subscript is denoted by an open bracket ([), followed by an arithmetic expression, followed by a close bracket (]) as in the following example: ${student[32]} To assign values to an array, use the format set -A name value... The value of all subscripts must be in the range 0 through January 1992 65



ksh(1) ksh(1)
1024. Arrays need not be declared prior to their use. Any reference to a name with a valid subscript is legal, and an array is created if necessary. Referencing an array without an index subscript is equivalent to referencing the first element. The following list shows the various syntaxes you can use when referring to variables: ${variable-name} ${array-name[index-expression]} Replace the variable or array specified with its value, if any. The braces are required when variable-name is followed by a letter, digit, or underscore that is not supposed to be interpreted as part of its name. If variable-name is specified as * or @, all the values of positional variables, starting with $1, are used as the substitution text (separated by a field-separator character). If the value of index-expression is given as * or @, the value for each of the elements of the array is used as the substitution text (separated by a field- separator character). ${#variable-name} Replaces the variable specified with the length of the string stored in variable-name. If variable-name is specified as an asterisk (*) or an ``at'' sign (@), the replacement value is the number of positional parameters that are set. ${#array-name[*]} Replaces the array specified with the number of elements in the array. ${variable-name:-word} ${variable-name-word} Replace the variable specified with its value if it is set and it is not empty; otherwise the replacement value is word. In the second form, the replacement value is word only if the variable is unset. ${variable:=word} Replaces the variable specified with its value if it is set. If it is unset or is empty, this syntax assigns word to the variable and also uses word as the replacement value. You cannot assign positional parameters this way. 66 January 1992



ksh(1) ksh(1)
${variable-name:?word} ${variable-name?word} Replace the variable specified with its value if it is set and it is not empty; otherwise print word on the standard error and exit from the shell. If word is omitted, print a standard message. In the second form (without a colon preceding the question mark), the message is displayed only if the variable is unset. ${variable-name:+word} ${variable-name+word} Replace the variable specified with its value if it is set and it is not empty; otherwise, substitute nothing. In the second form, if the value of the variable specified is an empty string, then word is used as the replacement value. ${variable-name#pattern} ${variable-name##pattern} Replace the variable specified with its truncated value, if pattern matches the beginning of its value. The truncated value is its original value less the characters matched by the search pattern. Otherwise, the replacement value is the complete value of variable-name. In the first form, the smallest matching pattern is deleted. In the second form, the largest matching pattern is deleted. ${variable-name%pattern} ${variable-name%%pattern} Replace the variable specified with its truncated value, if pattern matches the end of its value. The truncated value is its original value less the characters matched by the search pattern. Otherwise, the replacement value is the complete value of variable-name. In the first form, the smallest matching pattern is deleted. In the second form, the largest matching pattern is deleted. In the preceding variable-referencing syntaxes, the value of word is not examined unless it is to be used as the substituted string. Thus, in the following example, $HOME is subject to variable substitution only if d is not set or is empty: echo ${d:- $HOME} January 1992 67



ksh(1) ksh(1)
Functions You use the function keyword to define shell functions. When a function is declared, its command list is read, processed for substitutions such as aliases, and stored in memory. You can use either of these syntaxes for a function declaration: function identifier { list;} identifier() { list;} The command list is executed whenever the function is referenced. Inside the declared command list for a function, references to positional variables ($1, $2, $3, and so forth) access the values passed in a parameterized reference to the function: function-name([positional-arg]...) The only way to make the original positional parameters available inside the declared commands for the function is to rereference them when calling the function: function-name(one two "$@" ) Because of the introduction of two new positional parameters in the preceding reference to a function, the first positional parameter of the shell would have to be referenced in terms of $3 inside the declared commands for the function function-name. Another common element inside the declared commands for a function is the command return, which is used to exit the function and return to the point from which the function was called. See the description of return in ``Built-in Commands,'' later, for a description of its argument and its default return value. When the return command is not used as the means to exit a function, the value of the function is the exit value of the last command executed within the declared commands for a function. You can use typeset with the -f option or the +f option to list the functions that have been declared. (See ``Built-in Commands,'' later.) If you use the -f option, typeset lists the declared commands for the functions as well as the function names. You can undefine functions by using the 68 January 1992



ksh(1) ksh(1)
unset command with the -f option. (See ``Built-in Commands,'' later.) Ordinarily, functions are not exported to subshells, such as the subshells that execute shell scripts. However, you can export functions from the parent shell where they were declared to any of its subshells by using typeset with the -x and -f options. To allow functions to remain defined across login sessions, place the function declarations in the file referenced by ENV, as described earlier in ``Establishing Preference Settings.'' Errors within functions cause an exit from the function, returning execution to the point from which it was called. For a function call that runs without errors, the last command (possibly a return) executes followed by any commands set to run upon the receipt of an EXIT signal (see the description of the trap command in ``Built-in Commands,'' later). Functions execute in the same process as the shell in which they were invoked. They share all of the shell's opened input and output streams, all of its traps (other than EXIT and ERR), and its current working directory. An EXIT signal can be specified for a trap command placed inside the declared commands for a function. In such a case, the command associated with the trap runs after the function completes. The shell and the called function ordinarily share variables. However, the typeset command can be used within a function to create instances of local variables. The scope of these local variables includes the current function and all of the functions that it calls. Lexical Rules for Identifiers The names you choose for variables and functions can vary widely, but are subject to certain limitations. Throughout this manual page, the use of the term ``identifier,'' and the use of the placeholder identifier, imply adherence to these rules. An identifier must be a sequence of letters, digits, or underscores, starting with a letter or underscore. Identifiers cannot include shell metacharacters. Built-in Commands Sometimes it is useful to call a subshell simply for access to the built-in commands that are not available otherwise. For example, the capabilities of the built-in print command are not available in other shells, so you may need to call January 1992 69



ksh(1) ksh(1)
ksh solely to use its version of the print command. In a case such as this, you may need to use the -c option for ksh as described in ``Arguments,'' earlier in this manual page. The commands listed in this section execute within the same process as ksh rather than through an independent process based upon an executable A/UX file. For these commands, the usual search moderated by the PATH variable need not be performed. For this reason, these commands are called ``built-in'' commands for the ksh shell. Input/output redirection is permitted. Unless otherwise indicated, the output is written on the standard output channel (file descriptor 1). Error processing differs slightly for commands that are preceded by two daggers (††). When one of these commands produces an error within a shell script, both the shell script and the command are terminated. Commands that are preceded by one dagger symbol (†) are given the following special treatments: ⊕ One or more variable assignments preceding the command remain in effect after the command runs. ⊕ These commands are executed in a separate process when invoked as part of a command substitution. † : [arg]... Runs a null command that returns a 0 exit code. The arguments are processed in terms of argument parsing and variable substitution. †† . file [positional-value]... Reads and executes commands from file before returning to the interactive interpretation of command lines. The commands are executed in the current shell environment. The search path specified by PATH is used to find the directory containing file. If any arguments are given, they become the values of the positional parameters. Otherwise, the positional parameters are unchanged. alias alias alias-name alias [-tx] [alias-name=command-line]... Display or create aliases. To display a list of the aliases that have been set up already, use alias with no other arguments. To display a single alias, use the 70 January 1992



ksh(1) ksh(1)
second form of the command. To set up an alias to refer to a command line, use the third form of the command. A trailing space in command-line causes the first command name to be checked for alias substitution. Use the -t option to set and list tracked aliases. The value of a tracked alias is the full pathname corresponding to the given name. The value becomes undefined when the value of PATH is reset, but the aliases continue to be tracked aliases afterwards. The -x option is used to either establish or print exported aliases, depending on whether you supply an argument string. An exported alias remains defined in subshells, including those needed to run shell scripts. The alias command returns a 0 exit status unless you specify a name for which no alias has been defined. bg [%job] Places the specified job in the background. The current job is put in the background if job is not specified. † break [n] Exits from the enclosing for, while, until, or select loop, if any. If you specify n, break exits from n levels of nested control structures (if they exist). cd [directory] cd old new Reset the current working directory. The first form of the command changes the current directory to directory. If you specify directory as -, the directory is changed to the previous directory. The setting for the shell variable HOME is used as the default directory when no directory argument is specified. After successful execution, cd sets the variable PWD to the new current directory. If the directory can be found in any of the directory paths stored in the variable CDPATH, then directory is expanded to the first base pathname in CDPATH that contains directory. For example, if a directory named /usr/tools exists and /usr is one of the directories stored in CDPATH, you can enter cd tools to establish /usr/tools as your current directory. Alternative directory names are separated by colons January 1992 71



ksh(1) ksh(1)
(:). Initially, CDPATH is empty so that the current directory is used as the search directory. To ensure that the current directory will continue to be part of the search order, include a null directory in the list of paths: CDPATH=::$HOME/Tools When you specify directory with a leading slash (/), no search is performed. Otherwise, each directory in the CDPATH list is searched for directory. The second form of cd substitutes the string new for the string old in PWD, the current directory name, and tries to change to this new directory. † continue [n] Resumes the next iteration of the enclosing for, while, until, or select loop immediately. If you specify n, continue resumes execution at the beginning of the nth enclosing loop. echo [arg]... Displays arguments after the interpretation of shell metacharacters. The built-in echo command writes its arguments (separated by blanks and terminated by a return on the standard output). See echo(1) for additional information. The echo command is useful for producing diagnostics in shell programs and for writing constant data on pipes. To send diagnostics to the standard error file, use echo string1>&2 † eval [command-producing-arguments] Processes its arguments for command and variable substitution and for filename generation before submitting the resulting output to the current shell for further (and similar) processing as a command line. The following command sequence displays your home directory because variable substitution is performed twice: homeprint='echo $HOME' eval $homeprint † exec command 72 January 1992



ksh(1) ksh(1)
exec redirection-request Treat the arguments as command input, but do not return to the parent shell, as if the parent shell had exited upon the completion of the command(s). The command(s) replace the shell without creating a new process. Any previously open file descriptors above 2 are closed when this command invokes another program. You can use the second form of the command to reset the files (or devices) associated with various file descriptors, such as standard input, standard output, and standard error. (See ``Input/Output Redirection,'' earlier.) Unlike redirections that are requested for other commands, these redirections affect the current shell's execution environment, and, through inheritance, the execution environment of any commands subsequently run. † exit [status] Causes the shell to exit with the exit status specified by status. If status is omitted, the exit status is that of the last command executed. An end-of-file character also causes the shell to exit unless you have established the ignoreeof option. (See the description of set, later in this list.) †† export [variable]... Sets the export attribute for the named variables. †† fc [-e editor] [-nlr] [lineno] fc [-e editor] [-nlr] [start-command] [end-command] fc -e - [old=new] [command] fc -l [rn] n-history-lines Display, optionally edit, and dispatch previous commands. The redispatched commands, if any, are displayed in their final edited form upon leaving editing mode, then executed. In any of the command formats, the operation of fc depends on reasonable settings for the variables HISTSIZE (the maximum number of commands recallable) and HISTFILE (the name of the file in which the command history is saved). Refer to the earlier section ``Establishing Preference Settings'' for more introductory information. If you specify a negative number for lineno, start-command, n-history-lines, or end-command, the system calculates the final line number by reducing the January 1992 73



ksh(1) ksh(1)
most recent command number by an amount equal to the absolute value of the number you supplied. The arguments start-command, end-command, and lineno can be specified as numbers or as strings. Specify a string to locate the most recent command that begins with a particular string. If you don't specify editor, the value of the variable FCEDIT is used. If FCEDIT is empty, /bin/ed is used. Use the last form of the command, requiring the -l option, to list the given number of recently executed commands along with their line numbers. To reverse the order in which commands are listed, include the -r option. To prevent the line numbers from being listed along with the command, include the -n option. In the first form, a preceding command corresponding to lineno is rerun after it has been edited with editor. In the second form, a preceding range of commands starting with start-command and continuing through end-command are rerun after it has been edited with editor. When editing is complete, the edited command(s) are executed. If end-command is not specified, only start-command is executed. If you specify neither start-command nor end-command, the most recent command is used. Use the third form of the command, requiring the editor name to be supplied as -, to skip the editing phase and to reexecute the command. In this case, you can use a substitution of the form old=new to modify the command ``on the fly'' before execution. For example, suppose r is aliased to 'fc -e -'. If you enter r bad=good c the most recent command that starts with the letter c is executed once the first occurrence of the string bad is replaced with the string good. fg [%job] Converts a previously run command from background to foreground mode. If job is specified, it is brought to the foreground. Otherwise, the most recent background 74 January 1992



ksh(1) ksh(1)
job is brought to the foreground. getopts opt-string name [arg]... getopts [:][flag-letter[:]]...var-name[script-opts] Parse the string script-opts into its component options as does the stand-alone command getopt. For each call to getopts, the variable var-name is assigned the next option letter parsed from the string script-opts. If a plus sign precedes the option in script-opts, var-name will contain a leading plus sign as well as the flag letter. You can specify a trailing colon for any flag-letter argument. A trailing colon causes getopts to expect that option to be followed by its own argument inside the string script-opts. When this parsing mode is established, the argument parsed is stored in the variable OPTARG. (The options can be separated from the argument by blanks.) If script-opts is omitted, the positional parameters are used. The parsing rules for getopts interpret any letter in script-opts preceded by a + or a - as a distinct option. When it parses a substring that doesn't begin with either a plus or a minus sign, or that consists of two hyphens (--), getopts assumes that it has reached the end of the options list. Any further calls to getopts produce an error message and a nonzero exit value. The getopts program keeps a count of the items parsed so far. The number of the next item that will be parsed is available in the variable OPTIND. Errors are also reported when an option is parsed that is not recognized as one of the flag-letter items specified. A leading : before the first flag-letter argument changes the mode with which getopts handles certain types of errors so that it doesn't report an error message. In this mode, getopts stores the letter of an invalid option in OPTARG, and stores either ? or : in var-name. The value stored in var-name will be a question mark when the error is due to receipt of an unexpected option; it will be a colon when a required option argument is missing. jobs [-l] Lists the active jobs. If you specify the -l option, the list includes the process ID for each job along with the usual information. kill [-signal] process-no... Sends either the TERM (terminate) signal or the specified signal to the specified jobs or processes. Signals are given either by number or by name (as given in /usr/include/signal.h, stripped of the prefix SIG). January 1992 75



ksh(1) ksh(1)
Use kill with the -l option to list the signal numbers and names. If the signal you send to a job that is stopped is TERM (terminate) or HUP (hangup), kill sends a CONT (continue) signal. The argument process-no can be either a process ID or a job. See also kill(1). let[ variable=expr]... Evaluates each arithmetic expression, expr, assigning the result to the named variable. All calculations are executed with long integers, and no check for overflow is performed. Expressions consist of constants, variables, and operators. The following set of operators, listed in order of decreasing precedence, have been implemented: - unary minus ! logical negation * / % multiplication, division, modulo + - addition, subtraction <= >= < > comparison == != equality, inequality Subexpressions in parentheses are evaluated first and can be used to override the precedence rules listed. The evaluation within a precedence group is from right to left for the = operator and from left to right for the others. † newgrp [newgrp-arg]... Runs the newgrp command in place of the current shell as if the command exec /bin/newgrp... had been used. print [-nprRs][-ufiledes] [arg]... Prints its arguments on standard output, separating them with spaces, and normally adding an end-of-line character after the arguments. The print command accepts the following options: -p Causes the arguments to be written onto the pipe of the process spawned with |& instead of to standard output. -n Suppresses the addition of an end-of-line character to the end of the output string. 76 January 1992



ksh(1) ksh(1)
-r -R Cause a backslash (/) to be interpreted as data rather than as a metacharacter when it precedes a, b, c, f, n, r, t, v, \, or 0. The -R option also affects the way print recognizes command options so that all subsequent options other than -n are treated as data rather than as elements of the command. -s Causes the arguments to be written to the history file rather than to standard output. -ufiledes Specifies the one-digit file descriptor on which the output will be placed. The default is 1. Using this option is similar to redirecting output in the normal way, except that the print command does not cause the file (if any) to be opened and closed or the file descriptor to be duplicated each time. pwd Displays the currently selected working directory. read [-prs][-ufiledes] [variable?prompt] [variable]... Reads a line of text input, assigning it to variable. The shell reads one line of input, parses it into fields, using the characters in IFS as separators, and assigns the resulting field values to the specified variables, one field per variable. If there are fewer variables specified than fields parsed, the last variable specified is assigned the contents of two or more fields. If no variable names are specified, the input text is stored in the variable REPLY. If the shell is running interactively and the first field contains a ?, the remainder of that field is treated as an input prompt. The return code is 0 unless an end-of-file character is encountered. The read command accepts the following command options: -p Causes the input line to be taken from the input pipe of a process spawned by the shell by means of |&. If an end-of-file character is received, it closes the so-redirected process and another so- redirected process can be spawned. -r Reads in a raw character mode so that a backslash (\) is treated as data rather than as a metacharacter. -s Saves the input text in the history file. January 1992 77



ksh(1) ksh(1)
-u[filedes] Specifies a one-digit file descriptor, selecting a source of text stream input. You can use the built-in command exec to establish the file or device to be associated with a particular file descriptor. The default value of n is 0. If the file descriptor specified is open for writing and is a terminal device, any prompt specified is sent to that terminal instead of the standard error. †† readonly [variable=value] readonly [variable]... Make the specified variables read-only. These variables cannot be changed by subsequent assignment. † return [n] Returns execution to the original place in a script where a user-defined function was called, with the return status specified by n. If you omit n, the return status is that of the last command executed. If you invoke return outside the declared commands for a function, it has the same effect as the built-in exit command. set set [aefhkmnostuvx] [-o option]... [positional-param]... set -A array [value]... set +A array [value]... Display or set operating modes or array elements. To display the options that are currently established, use the first form of the command, with no arguments. This format displays the values of all variables affecting shell operation. To set modes of operation for the shell, use the second form of the command which has many selectable options (aefhimnostuvx). See the description of each of these options in the ``Arguments'' section at the beginning of this manual page. The second form of the command resets the positional parameters. The supplied values are parsed (as described in ``Argument Parsing'') and each resulting argument is assigned to the variables: $1, $2, and so forth. Use the third form to nullify (unset) and reset the values stored in array, assigning them new values for as many elements as there are values offered. Use the fourth form of the command to add and assign new 78 January 1992



ksh(1) ksh(1)
members to an array. If you specify +A rather than -A, the old values are not unset first, and the number of array elements is increased by the number of values given. † shift[n] Reassigns the value of each of the positional parameters according to the value stored in the parameter n positions away. For example, shift 1 causes $1 to be assigned the value of $2, $2 to be assigned the value of $3, and so forth. The default shift value for n is 1. You can replace n with any arithmetic expression that evaluates to a nonnegative number less than or equal to the total number of positional parameters set, as given by $#. test argument... Evaluates its arguments to produce a Boolean value as described in test(1). The same functionality is available through the [[ argument ]] construct as described earlier in ``Conditional Expressions.'' † times Prints the accumulated user and system times for the shell and for processes run from the shell. † trap command [signal]... trap - signal... trap "" signal... trap Execute the command specified when the shell receives the signal(s) named. The value of signal can be a number or the name of the signal. Trap commands are executed in order of signal number. When entered in the second format shown, where the command is specified as -, trap resets the handling of the specified signals to their default treatment. When entered in the third format shown, without any arguments, trap prints a list of the already established commands for each signal along with the signal number. When entered in the fourth format shown, where the command is specified with the null string, signals are set to be ignored for the current shell and any subshells. Within subshells, you cannot set a trap on a signal that was set to be ignored by the parent shell. If signal is ERR, command is executed whenever a command has a nonzero exit code. This trap is not inherited by functions. If signal is 0 or EXIT and the January 1992 79



ksh(1) ksh(1)
trap statement is executed inside the declared commands for a function, the command is executed after the function completes. If signal is 0 or EXIT for a trap command entered normally (not inside a function), the associated command is executed upon exit from the shell. †† typeset -i[Hrtx][LR[Z]width]] [variable[=integer]]... typeset -i[Hrtx][base] [variable[=integer]]... typeset +i[Hrtx][variable[=integer]]... typeset -f[tu] [function]...] typeset +f[tu] [function]...] Set, unset, or display the attributes and values for shell integer variables or shell functions. All options that are not described here are the same as those described in the next list, where typeset is treated more generally. Options described here are either exclusively for integers or functions, or they function differently for integers or functions. -f +f Cause the remaining arguments to be interpreted appropriately for functions. Use +f to turn off the trace mode (-t), unresolved name (-u), and (- x) exported attributes by following it with the appropriate option letter. -i[base] +i Cause the values of the specified variable(s) to be treated as integers, making arithmetic speedier. If base is nonzero, it defines the output arithmetic base; otherwise, the first assignment determines the output base. Use +i to turn off the read-only (-r), tagged (-t), and exported (-x) attributes by following it with the appropriate option letter. -t function... Specifies that trace mode will be in effect when the specified function is run. To be effective, this option must be preceded by the -f option. -u Declares the specified function(s) as currently undefined. The FPATH variable is searched to find the function definition when the function is referenced. To be effective, this option must be preceded by the -f option. -x Marks the named function(s) for automatic export, allowing the function(s) to remain in effect in subshells in the same process environment. To be 80 January 1992



ksh(1) ksh(1)
effective, this option must be preceded by the -f option. †† typeset typeset + typeset - typeset -[Hlrtux][LRwidth] [variable[=value]]... typeset +[Hlrtux] [variable[=value]]... Set, unset, or display the attributes and values for shell variables. If no arguments are specified (the first command format shown), the names and attributes of all variables are displayed. With no arguments but + (the second command format shown), typeset displays the names of all variables, but not their values. With no arguments but - (the third command format shown), typeset displays the names and current values of all variables. When variables are specified as arguments, typeset changes their attributes in accordance with any options you supply. With options that can be toggled on and off, such as H, l, r, t, u, and x, typeset activates the setting when you precede the option letter with a hyphen (-), and disables it when you precede the option letter with a plus (+). When no variables are specified as arguments, yet option letters are present, typeset lists the names and values of the variables that have the specified options enabled. In such cases, if you precede the option letters with a plus sign instead of a minus sign, only the names of the variables that have the named options set are displayed. When this command is invoked inside a function, a local instance of the variable is created. If a global variable by the same name exists, then its value outside of the function corresponds to that of the global variable. The following options are accepted: -H Provides A/UX-to-host namefile mapping on non-UNIX machines. -l Converts all uppercase characters assigned to the named variable(s) to lowercase. Turns off the uppercase option, -u. -L Left-justifies and removes leading blanks from January 1992 81



ksh(1) ksh(1)
value. If width is nonzero, this option defines the width of the field; otherwise the width is determined by the width of the value first assigned to the variable. When a value is assigned to the variable, it is filled on the right with blanks or truncated, if necessary, to fit into the field. Leading zeros are removed if the -Z option is also set. The -R option is turned off. -r Makes the named variable(s) read-only. These variables cannot be changed by subsequent assignment. -R Right-justifies and adds leading blanks. If width is nonzero, this option defines the width of the field; otherwise the width is determined by the width of the value first assigned to the variable. The field is filled with blanks or truncated from the end if the variable is reassigned. The L option is turned off. -t Sets the ``tagged'' attribute for the named variable(s). Tags are user-definable and have no special meaning to the shell. -u Converts all lowercase characters assigned to the named variable(s) to uppercase. Turns off the lowercase option, -l. -x Marks the named variable(s) for automatic export to the environment of subsequently executed commands. -Z [-Z]width Establishes leading zero as the fill character when right-justifying a numeric value in a field width characters wide. A variable need only contain a single digit as the first nonblank character to be treated as a numeric value. This option is incompatible with the left-justification (-L) option. Using this option is equivalent to using the -R and -Z options together. The width can also be determined dynamically based on the content first assigned to the variable. ulimit [acdfmnpstv][limit] ulimit -H[acdfmnpstv][limit] ulimit -S[acdfmnpstv][limit] Set or display a resource limit. The available resource limits are listed later in this description. 82 January 1992



ksh(1) ksh(1)
Many systems do not contain one or more of these limits. The limit for a specified resource is set when a limit number is specified. Alternatively, you can specify unlimited for limit. Use the H option or the S option to specify whether the hard limit or the soft limit is desired. A hard limit cannot be increased once it is set. A soft limit can be increased up to the value of the hard limit. If you specify neither the H or the S option, the limit applies to both. The current resource limit is printed when limit is omitted. In this case the soft limit is printed unless H is specified. When more than one resource is specified, the limit name and unit are printed before the value. If no option is given, -f is assumed. -a Lists all of the current resource limits. -c Displays the number of 512-byte blocks available for core dumps. -d Displays the number of kilobytes available for the data area. -f Displays the number of 512-byte blocks available for files written by child processes (files of any size may be read). -m Displays the number of kilobytes available for physical memory. -n Displays the number of file descriptors available. -p Displays the number of 512-byte blocks available for pipe buffering. -s Displays the number of kilobytes available for the stack area. -t Displays the number of seconds available for each process. -v Displays the number of kilobytes available for virtual memory. umask umask complemented-chmod-digits umask chmod-opstring Set the user file-creation mask to the octal value complemented-chmod-digits. (See umask(2).) You can also specify a chmod-opstring argument as described in chmod(1). In that case, the new value of umask is recomputed based on the old value and the change in January 1992 83



ksh(1) ksh(1)
that value requested by chmod-opstring. If umask is entered with no argument, the current value of the mask is printed. unalias alias... Removes the named aliases. unset [-f] variable... Unsets the named variables. Unsetting these variables erases their values and their attributes. Read-only variables cannot be unset. If the -f option is set, the names refer to function names. Unsetting ERRNO, LINENO, MAILCHECK, OPTARG, OPTIND, RANDOM, SECONDS, TMOUT, and _ removes their special meaning, even if you subsequently assign them values. wait [pid] wait %n Wait for the specified child process and report its termination status. If process is not given, wait suspends shell operation until all currently active child processes terminate. The exit status from this command is the same as that of the process on which it was waiting. See ``Controlling Jobs Not in the Foreground,'' earlier, for a description of the format of n. whence [-pv] name... For each name, displays information about how a command named name would be interpreted. The output could include information about command locations on a given system and account, and about current alias settings. The -v option produces a more verbose report. The -p option causes a path search to take place even when name is an alias, a function, or a reserved word. Shell-Maintained, Built-in Variables The following variables are automatically maintained by ksh. If you unset some of these variables, ksh removes their special meaning even if you subsequently set them. ! Contains the process number of the last background command invoked. # Contains the number of positional parameters in decimal. $ Contains the process number of this shell. - Contains the preferences currently set, whether they were set upon shell invocation or through the set 84 January 1992



ksh(1) ksh(1)
command. ? Contains the decimal exit value returned by the last executed command. _ (Underscore) Contains the last argument of the previous command. This parameter is not set for asynchronous commands. This parameter is also used to hold the name of the matching MAIL file when the system is checking for mail. Finally, the value of this parameter is set to the full pathname of each program the shell invokes and is passed in the environment. Unsetting this variable removes its special meaning. A_z Contains information about exported variables that have special meaning, or that have been made read-only. ERRNO Contains the value of errno as set by the most recently failed system call. This value is system dependent and is intended for debugging purposes. Unsetting this variable removes its special meaning. LINENO Contains the line number of the current line within the script or function being executed. Unsetting this variable removes its special meaning. OLDPWD Contains the previous working directory set by the cd command. OPTARG Contains the value of the last option argument processed by the getopts built-in command. Unsetting this variable removes its special meaning. OPTIND Contains the index of the last option argument processed by the getopts built-in command. Unsetting this variable removes its special meaning. PPID Contains the process number of the parent of the shell. PWD Contains the present working directory set by the cd command. RANDOM Generates a random integer each time this pseudo variable is referenced. You initiate the sequence of random numbers by assigning a numeric value to RANDOM. Unsetting this variable removes its special meaning. January 1992 85



ksh(1) ksh(1)
REPLY Contains the error message set through the select command and displayed by the read command when no arguments are entered. SECONDS Contains the duration of time that the shell has been running, in seconds. If this parameter is assigned a value, the value returned is the value that was assigned plus the number of seconds since the assignment. Unsetting this variable removes its special meaning. Other Built-in Variables The following variables are used by the shell. In A/UX, the default values shown may have been set (by means of a .profile or .kshrc file) to different values. CDPATH Contains a list of directory paths used by the cd command to expand arguments that match the base component of one of the directory paths. COLUMNS Defines the width of the edit window, if set. Applies to shell edit modes and to the display of character- oriented menus through the select command. EDITOR Contains the user preference for choice of command editor. If the value of this variable ends in emacs, gmacs, or vi and the VISUAL variable is not set, the corresponding command option is turned on. (See ``Built-in Commands,'' earlier.) ENV Contains the pathname for the file from which initial commands are read and performed by each new ksh process as it starts up. By default, this variable is set to the file .kshrc in your home directory. (Variable substitution is performed again on the value stored in ENV to help generate the final pathname, permitting the use of a reference to yet another variable such as $HOME.) This ``startup'' file is typically used for alias and function definitions that you want to remain available in any subshells you might run. FCEDIT Contains the default editor name for the fc command. IFS Contains the characters to be used as field separators. 86 January 1992



ksh(1) ksh(1)
Normally the field separators are the space, tab, and newline characters. Affects command and parameter substitution as well as the built-in command read. When the shell generates certain values such as the value of $*, it uses the first character stored in IFS as the character separating one positional parameter from the next. (Also see ``Filename Generation,'' earlier.) HISTFILE Contains the pathname of the file that is used to store previously entered command lines. If this variable is not set, no record of previously entered command lines is kept. (See ``Command Reentry,'' earlier.) HISTSIZE Contains the maximum number of previously entered lines that will be available to the command editor, if HISTFILE has been set. The default is 128. Setting this variable to a relatively large value, such as 10000, may result in a delay for each new invocation of ksh. HOME Contains the pathname corresponding to the login directory for the current user. When given no arguments, the cd command establishes this directory as the working directory. LINES Defines the length of the edit window, if set. Applies to shell edit modes and to the display of character- oriented menus through the select command. MAIL Contains the name of your mail file when set. If MAIL is set and if the MAILPATH is not set, the shell notifies you of the arrival of mail in the specified file. MAILCHECK Specifies in seconds how often the shell checks for changes in the modification time of any of the files specified by the MAILPATH or MAIL variable. The default value is 600 seconds. When the time has elapsed, the shell checks for mail before issuing the next prompt. Unsetting this variable removes its special meaning. MAILPATH Contains a list of filenames separated by colons (:). If this variable is set, the shell informs the user of any modifications to the specified files that have occurred within the last MAILCHECK seconds. Each January 1992 87



ksh(1) ksh(1)
filename can be followed by a ? and a message that will be printed. The message undergoes parameter and command substitution, and the variable $_ is set to the name of the file that has changed. The default message is produced by the following message: you have mail in $_ PATH Contains a list of the directories to be searched for command files or command scripts. PS1 Contains the string that the shell displays to prompt you for a command. This string is subject to parameter substitution. By default, it is set to $. The metacharacter ! in the prompt string is replaced by the command number (See ``Command Reentry,'' earlier.) Two successive occurrences of ! produce a single ! when the prompt string is printed. PS2 Contains the string that the shell displays to prompt you for a block of commands to be executed together. By default, this variable is set to >. PS3 Contains the string that the shell displays to prompt you for a select choice. By default, this variable is set to #?. PS4 Contains the string that the shell displays before each line of an execution trace. The value of this variable is expanded for parameter substitution. If PS4 is unset, the execution trace indicator is set to a plus sign (+). SHELL Contains the pathname to the login shell preference for a particular account, and is stored in the processing environment. A leading r in the filename indicates that the login shell is restricted. TMOUT Contains the amount of time in seconds that the system will wait for input before exiting. (The shell can be compiled so that it will establish a maximum value for this variable.) Unsetting this variable removes its special meaning. VISUAL Contains the user preference for choice of command editor. If the value of this variable ends in emacs, gmacs, or vi, ksh turns on the corresponding option regardless of the setting stored in the EDITOR 88 January 1992



ksh(1) ksh(1)
variable. The shell gives default values to PATH, PS1, PS2, MAILCHECK, TMOUT, and IFS. The shell does not set initial values for ENV and MAIL. Initial values for HOME, MAIL, and SHELL are set by login and inherited by the shell as part of its execution environment. STATUS MESSAGES AND VALUES Errors detected by the shell, such as syntax errors, cause the shell to return a nonzero exit status. Otherwise, the shell returns the exit status of the last command executed. (See also the description of the exit command in ``Built-in Commands,'' in the ``Description'' section.) If the shell is being used noninteractively, execution of the shell file is abandoned. The system reports run-time errors for shell scripts by printing the command or function name and the error condition. If the number of the line on which the error occurred is greater than 1, the line number is also printed in square brackets ([]) after the command or function name. WARNINGS If a command that is a tracked alias is executed, and then a command with the same name is installed in a directory in the search path prior to the directory where the original command was found, the shell continues to execute the original command. Use the -t option of the alias command to correct this situation. Some very old shell scripts use a caret (^) as a synonym for the pipe character (|). This synonym is not supported in releases of A/UX later than 2.0. If a command is piped into a shell command, all variables set in the shell command are lost when the command is executed. Using the fc built-in command within a compound command causes the whole command to disappear from the history file. The built-in dot command (.) reads the whole file named file before any commands are executed. Thus, for . file any alias and unalias commands in file will not be available within file. Traps are not processed while a job is waiting for a foreground process. Thus a trap on CHLD won't be executed January 1992 89



ksh(1) ksh(1)
until the foreground job terminates. Unsetting some special variables removes their special meaning, even if they are subsequently set. When you log in over a serial line, the command-input editing options may require specific settings of the configuration switches of the associated terminal device. FILES $HOME/.profile User-specific ksh startup settings file /bin/ksh Executable file /etc/passwd Password and login-account information file /etc/profile System-wide ksh startup-settings file /etc/suid_profile File from which startup settings are obtained for subshells invoked to run for a script that has setuid or setgid permission /tmp/ksh* Temporary file SEE ALSO cat(1), chmod(1), CommandShell(1), csh(1), echo(1), ed(1), env(1), getopt(1), kill(1), launch(1), login(1), newgrp(1), nice(1), printenv(1), ps(1), sh(1), startmac(1), stty(1), tee(1), vi(1) dup(2), exec(2), fork(2), ioctl(2), lseek(2), pipe(2), ulimit(2), umask(2), wait(2), signal(3), rand(3C), a.out(4), passwd(4), profile(4), termcap(4), terminfo(4), environ(5) in ``Korn Shell Reference'' in A/UX Shells and Shell Programming Bolsky, Morris, and David Korn. The KornShell Command and Programming Language. Englewood Cliffs, NJ: Prentice-Hall, 1989. 90 January 1992

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026