ksh - public domain Korn shell
ksh [+-abCefhikmnprsuvxX] [+-o option] [[-c command-string
[command-name] | -s | file ] [argument ...]]
The ksh(1) utility is a command interpreter that is intended for both interactive and shell script use. Its command language is a superset of the sh(1) shell language.
The version here contains the features of the ksh88 version, dated 11/16/88.
The following options can be specified only on the command line:
In addition to the options already mentioned, the options described in the set built-in command can also be used on the command line.
If neither the -c nor the -s option is specified, the first non-option argument specifies the name of a file from which the shell reads commands. If there are no non-option arguments, the shell reads commands from standard input. The name of the shell (that is, the contents of the $0 parameter ) is determined as follows:
If the -c option is used and there is a non-option argument, it is used as the name. If commands are being read from a file, the file is used as the name. Otherwise, the name with which the shell was called (that is, argv[0]) is used.
A shell is "interactive" if the -i option is used, or if both standard input and standard error are attached to a tty. An interactive shell has job control enabled (if available), ignores the INT, QUIT, and TERM signals, and prints prompts before reading input (see PS1 and PS2 parameters). For non-interactive shells, the trackall option is on by default (see set(1) command).
A shell is "restricted" if the -r option is used, or if either the basename of the name with which the shell is invoked or the SHELL parameter is rsh. The following restrictions apply after the shell processes any profile and $ENV files:
A shell is "privileged" if the -p option is used. The real user identifier (UID) or group identifier (GID) does not match the effective UID or GID (see getuid(2), getgid(2)). A privileged shell processes neither the $HOME/.profile nor the ENV parameter. Instead, it processes the file /etc/suid_profile. Clearing the privileged option causes the shell to set its effective UID (GID) to its real UID (GID).
If the basename of the name the shell is called with (that is, argv[0]) starts with -, or if the -l option is used, the shell is assumed to be a login shell. The shell then reads and executes the contents of /etc/profile and $HOME/.profile if they exist and are readable.
If the ENV parameter is set when the shell starts (or, in the case of login shells, after any profiles are processed), its value is subjected to parameter, command, arithmetic, and tilde substitution. The resulting file (if any) is read and executed. If ENV parameter is not set (and not null) and ksh(1) was compiled with the DEFAULT_ENV macro defined, the file named in that macro is included (after the above mentioned substitutions have been performed).
The exit status of the shell is 127 if the command file specified on the command line could not be opened, or non-zero if a fatal syntax error occurred during the execution of a script. In the absence of fatal errors, the exit status is that of the last command executed, or zero, if no command is executed.
The shell begins parsing its input by breaking it into "words." Words, which are sequences of characters, are delimited by unquoted white-space characters (space, tab, and newline) or meta-characters (< >, |, ;, &, (, and )). Aside from delimiting words, spaces and tabs are ignored; newlines usually delimit commands. Use the meta-characters to build the following tokens:
Token | Use |
---|---|
<, <&, <<, >, >&, >>, and so on | Specify redirections (see the section on input/output redirection) |
| | Create pipelines |
|& | Create co-processes (see the section on co-processes) |
; | Separate commands |
& | Create asynchronous pipelines |
&& and || | Specify conditional execution |
;; | Used in case statements |
( .. ) | Create subshells |
(( ..)) | Used in arithmetic expressions |
White-space characters and and meta-characters can be quoted individually using a backslash (\), or in groups, using double (") or single(') quotes. The following characters are also treated specially by the shell, and must be quoted if they are to represent themselves: \, ", ', #, $, ', ~, {, }, *, ?, and [. The first three of these are the above mentioned quoting characters (see the section on quoting). #, if used at the beginning of a word, introduces a comment — everything after the # up to the nearest newline is ignored. $ introduces parameter, command, and arithmetic substitutions (see the section on substitution). ' introduces an old-style command substitution (see the section on substitution). ~ begins a directory expansion (see the section on tilde expansion). { and } delimit csh(1) style alternations (see the section on brace expansion). The characters *, ? and [ are used in file-name generation (see the section on file-name patterns).
As words and tokens are parsed, the shell builds commands, of which there are two basic types: simple commands, typically programs that are executed; and compound commands, such as for and if statements, grouping constructs, and function definitions.
A simple command consists of some combination of parameter assignments (see the section on parameters), input/output redirections (see the section on input/output redirection), and command words. The only restriction is that parameter assignments come before any command words. The command words, if there are any, define the command that is to be executed and its arguments. The command can be a shell built-in command, a function, or an external command; that is, a separate executable file that is located using the PATH parameter (see the section on command execution). Note that all command constructs have an exit status: for external commands, this is related to the status returned by wait(3). The exit status of other command constructs (built-in commands, functions, compound-commands, pipelines, lists, and such) are all well defined and are described where the construct is described. The exit status of a command consisting only of parameter assignments is that of the last command substitution performed during the parameter assignment, or zero if there were no command substitutions.
Commands can be chained together using the | token to form pipelines, in which the standard output of each command but the last is piped (see pipe(2)) to the standard input of the following command. The exit status of a pipeline is that of its last command. A pipeline can be prefixed by the ! reserved word, which causes the exit status of the pipeline to be logically complemented: if the original status was 0, the complemented status will be 1, and if the original status was not 0, the complemented status will be 0.
Lists of commands can be created by separating pipelines using any of the following tokens: &&, ||, &, |&, and ;. The first two are for conditional execution: cmd1 && cmd2 executes cmd2 only if the exit status of cmd1 is zero; || is the opposite — cmd2 is executed only if the exit status of cmd1 is non-zero. && and || have equal precedence, which is higher than that of &, |&, and ;, which also have equal precedence. The & token causes the preceding command to be executed asynchronously; that is, the shell starts the command, but does not wait for it to complete (the shell does keep track of the status of asynchronous commands — for more information about this, see "Job control"). If an asynchronous command is started when job control is disabled (that is, in most scripts), the command is started with signals INT and QUIT ignored, and with input redirected from /dev/null. (However, redirections specified in the asynchronous command have precedence.) The |& operator starts a co-process, which is special kind of asynchronous process (see the section on co-processes). Note that a command must follow the && and || operators; a command need not follow &, |&, or ;. The exit status of a list is that of the last command executed, except for asynchronous lists, which have an exit status of 0.
Compound commands are created using the following reserved words. These words are only recognized if they are unquoted and if they are used as the first word of a command (that is, they cannot be preceded by parameter assignments or redirections):
case | else | function | then | ! |
do | esac | if | time | [[ |
done | fi | in | until | { |
elif | for | select | while | } |
Some shells (but not this one) execute control structure commands in a subshell when one or more of their file descriptors are redirected, so any environment changes inside them might fail. To be portable, the exec statement should be used instead to redirect file descriptors before the control structure.
In the following compound-command descriptions, command lists (denoted as list) that are followed by reserved words must end with a semicolon (;), a newline or a (syntactically correct) reserved word. For example, the following are all valid:
{ echo foo; echo bar; }
{ echo foo; echo bar<newline>}
{ { echo foo; echo bar; } }
The next example is not valid:
{ echo foo; echo bar }
For historical reasons, open and close braces can be used instead of in and esac (for example, case $foo { *) echo bar; }). The exit status of a case statement is that of the executed list; if no list is executed, the exit status is zero.
Redirections after the pipeline affect the last command in the pipeline, not the time(1) command.
[[ foobar = f*r ]]
[str]
[[-n str]]
[[ -r foo && $(< foo) = b*r ]]
the $(< foo) is evaluated only if the file foo
exists and is readable.Quoting is used to prevent the shell from treating characters or words specially. There are three methods of quoting. First, backslash (\) quotes the following character, unless it is at the end of a line, in which case both the \ and the newline are stripped. Second, a single quote (') quotes everything up to the next single quote (this can span lines). Third, a double quote (") quotes all characters, except $, ' and \, up to the next unquoted double quote. The characters $ and ' inside double quotes have their usual meaning (that is, parameter, command, or arithmetic substitution) except that no field splitting is carried out on the results of double-quoted substitutions. If a \ inside a double-quoted string is followed by \, $, ', or ", it is replaced by the second character. If it is followed by a newline, both the \ and the newline are stripped. Otherwise, both the \ and the character following are unchanged.
See POSIX mode in this topic for a special rule regarding sequences of the form "...'...\"...'..".
There are two types of aliases: normal command aliases and tracked aliases. Command aliases are usually used as an abbreviation for a long or frequently used command. The shell expands command aliases (that is, it substitutes the alias name for its value) when it reads the first word of a command. An expanded alias is reprocessed to check for more aliases. If a command alias ends in a space or tab, the following word is also checked for alias expansion. The alias expansion process stops when a word that is not an alias is found, when a quoted word is found, or when an alias word that is currently being expanded is found.
The following command aliases are defined automatically by the shell:
autoload='typeset -fu'
functions='typeset -f'
hash='alias -t'
history='fc -l'
integer='typeset -i'
local='typeset'
nohup='nohup '
r='fc -e -'
stop='kill -STOP'
suspend='kill -STOP $$'
type='whence -v'
Tracked aliases allow the shell to remember where it found a particular command. The first time the shell does a path search for a command that is marked as a tracked alias, it saves the full path of the command. The next time the command is executed, the shell checks the saved path to ensure that it is still valid, and if so, avoids repeating the path search. Tracked aliases can be listed and created using alias -t. Note that changing the PATH parameter clears the saved paths for all tracked aliases. If the trackall option is set (that is, set -o trackall or set -h), the shell tracks all commands. This option is set automatically for non-interactive shells. For interactive shells, only the following commands are automatically tracked: cat(1), cc(1), chmod(1), cp(1), date(1), ed(1), emacs(1), grep(1), ls(1), mail(1), make(1), mv(1), pr(1), rm(1), sed(1), sh(1), vi(1) and who(1). (Note that emacs(1) is not currently part of Windows Services for UNIX, and that cc(1) is available only in the Software Development Kit.)
The first step the shell takes in executing a simple command is to perform substitutions on the words of the command. There are three kinds of substitution: parameter, command, and arithmetic. Parameter substitutions, which are described in detail in the next section, take the form $name or ${...}. Command substitutions take the form $(command) or 'command'. Arithmetic substitutions take the form $((expression)).
If a substitution appears outside of double quotes, the results of the substitution are generally subject to word or field splitting, according to the current value of the IFS parameter. The IFS parameter specifies a list of characters that are used to break a string up into several words; any characters from the set space, tab, and newline that appear in the IFS characters are called IFS white space. Sequences of one or more IFS white-space characters, in combination with zero or one non-IFS white-space character delimit a field. As a special case, leading and trailing IFS white space is stripped (that is, no leading or trailing empty field is created by it); leading or trailing non-IFS white space does create an empty field.
For example: if IFS is set to '<space>:', the sequence of characters '<space>A<space>:<space><space>B: :D' contains four fields: 'A', 'B', '' and 'D'. If the IFS parameter is set to the null string, no field splitting is done. If the parameter is unset, the default value of space, tab, and newline is used.
The results of substitution are, unless otherwise specified, also subject to brace expansion and file-name expansion (see the relevant sections that follow).
A command substitution is replaced by the output generated by the specified command, which is run in a subshell. For $(command) substitutions, normal quoting rules are used when command is parsed. However, for the 'command' form, a \ followed by any of $, ', or \ is stripped (a \ followed by any other character is unchanged). As a special case, in command substitutions, a command of the form < file is interpreted to mean substitute the contents of file ($(< foo) has the same effect as $(cat foo), but it is carried out more efficiently because no process is started).
It should be noted that $(command) expressions are currently parsed by finding the matching parenthesis, regardless of quoting. It is hoped that this will soon be corrected.
Arithmetic substitutions are replaced by the value of the specified expression. For example, the command echo $((2+3*4)) prints 14. (See "Arithmetic Expressions" for a description of an expression.)
Parameters are shell variables; they can be assigned values and their values can be accessed using a parameter substitution. A parameter name is either one of the special single punctuation or digit character parameters described later, or a letter followed by zero or more letters or digits ('_' counts as a letter). Parameter substitutions take the form $name or ${name}, where name is a parameter name. If substitution is performed on a parameter that is not set, a null string is substituted unless the nounset option (set -o nounset or set -u) is set, in which case an error occurs.
Parameters can be assigned values in a variety of ways. First, the shell implicitly sets some parameters, like #, and PWD. This is the only way the special single-character parameters are set. Second, parameters are imported from the shell's environment at startup. Third, parameters can be assigned values on the command line. For example, DOG=cat sets the parameter DOG to cat. Multiple parameter assignments can be given on a single command line and they can be followed by a simple command, in which case the assignments are in effect only for the duration of the command (such assignments are also exported; the implications of this are discussed later). Both the parameter name and the = must be unquoted for the shell to recognize a parameter assignment. The fourth way of setting a parameter is with the export, readonly and typeset commands (see their descriptions in the command execution section). Fifth, for and select loops set parameters as well as the getopts, read and set -A commands. Sixth, parameters can be assigned values using assignment operators inside arithmetic expressions or using the ${name=value} form of parameter substitution.
Parameters with the export attribute (set using the export or typeset -x commands, or by parameter assignments followed by simple commands) are put in the environment (see environ(5)) of commands run by the shell as name=value pairs. The order in which parameters appear in the environment of a command is unspecified. When the shell starts up, it extracts parameters and their values from its environment and automatically sets the export attribute for those parameters.
Modifiers can be applied to the ${name} form of parameter substitution:
In the above modifiers, the : can be omitted, in which case the conditions only depend on name being set (as opposed to set and not null). If word is needed, parameter, command, arithmetic, and tilde substitution are performed on it; if word is not needed, it is not evaluated.
The following forms of parameter substitution can also be used:
The following special parameters are implicitly set by the shell and cannot be set directly using assignments:
The following parameters are either set, not used by the shell, or both:
If HISTFILE is not set, no history file is used. This is different from the original Korn shell, which uses $HOME/.sh_history. In the future, ksh(1) might also use a default history file.
This parameter is not imported from the environment when the shell is started.
you have mail in
$_
.Tilde expansion, which is done in parallel with parameter substitution, is done on words starting with an unquoted tilde character (~). The characters following the tilde, up to the first /, if any, are assumed to be a login name. If the login name is empty, + or -, the value of the HOME, PWD, or OLDPWD parameter is substituted, respectively. Otherwise, the password file is searched for the login name, and the tilde expression is substituted with the user's home directory. If the login name is not found in the password file, or if any quoting or parameter substitution occurs in the login name, no substitution is performed.
In parameter assignments (those preceding a simple command or those occurring in the arguments of alias, export, readonly, and typeset), tilde expansion is done after any unquoted colon (:), and login names are delimited by colons.
The home directory of previously expanded login names are cached and reused. The alias -d command can be used to list, change, and add to this cache (for example, 'alias -d fac=/local/facilities; cd ~fac/bin').
On a Windows system, tilde expansion depends upon the contents of the local password database. If the login name comes from another domain (even if you are logged into that domain), it is not checked for information, and the tilde is not properly expanded. As previously mentioned, you can use the alias -d command to add login names.
Brace expressions take the form prefix(str1,...,strN)suffix.
They are expanded to N words, each of which is the concatenation of prefix, stri and suffix (for example, 'a{c,b{X,Y},d}e' expands to four word: ace, abXe, abYe, and ade). As noted in the example, brace expressions can be nested, and the resulting words are not sorted. Brace expressions must contain an unquoted comma (,) for expansion to occur (that is, {} and {foo} are not expanded). Brace expansion is carried out after parameter substitution and before file-name generation.
A file-name pattern is a word containing one or more unquoted ? or * characters or [..] sequences. Once brace expansion has been performed, the shell replaces file-name patterns with the sorted names of all the files that match the pattern. (If no files match, the word is left unchanged.) The pattern elements have the following meanings:
Currently, ksh(1) never matches . and .., but the original ksh, Bourne sh and bash do, so this might change.
Note that none of the above pattern elements match either a period (.) at the start of a file name or a slash (/), even if they are explicitly used in a [..] sequence. Also, the names . and .. are never matched, even by the pattern .*.
If the markdirs option is set, any directories that result from file-name generation are marked with a trailing /.
The POSIX character classes (that is, [:class-name:] inside a [..] expression) are not yet implemented.
When a command is executed, its standard input, standard output, and standard error (file descriptors 0, 1 and 2, respectively) are normally inherited from the shell. Three exceptions to this are: commands in pipelines, for which standard input, standard output, or both, are those set up by the pipeline; asynchronous commands created when job control is disabled, for which standard input is initially set to be from /dev/null; and commands for which any of the following redirections have been specified:
In any of the above redirections, the file descriptor that is redirected (that is, standard input or standard output) can be explicitly given by preceding the redirection with a single digit. Parameter, command, and arithmetic substitutions; tilde substitutions; and file-name generation are all performed on the file, marker and fd arguments of redirections. Note, however, that the results of any file-name generation are only used if a single file is matched. If multiple files match, the word with the unexpanded file-name generation characters is used. In restricted shells, redirections that can create files cannot be used.
For simple commands, redirections can appear anywhere in the command. For compound commands (such as if statements), redirections must appear at the end. Redirections are processed after pipelines are created and in the order in which they are given, so:
cat /foo/bar 2>&1 > /dev/null | cat -n
will print an error with a line number prepended to it.
Integer arithmetic expressions can be used with the let command, inside $((..)) expressions, inside array references (for example, name[expr]), as numeric arguments to the test command, and as the value of an assignment to an integer parameter.
Expression can contain alphanumeric parameter identifiers, array references, and integer constants. Expressions can be combined with the following C operators (listed and grouped in increasing order of precedence).
Unary operators: | + - ! ~ ++ -- |
Binary operators: | , |
= *= /= %= += -= <<= >>= &= ^= |= | |
|| | |
&& | |
| | |
^ | |
& | |
== != | |
< <= >= > | |
<< >> | |
+ - | |
* / % | |
Ternary operator: | ?: (Precedence is immediately higher than assignment) |
Grouping operators: | ( ) |
Integer constants can be specified with arbitrary bases using the notation base#number, where base is a decimal integer specifying the base, and number is a number in the specified base.
The operators are evaluated as follows:
A co-process, which is a pipeline created with the |& operator, is an asynchronous process that the shell can both write to (using print -p) and read from (using read -p). The input and output of the co-process can also be manipulated using >&p and <&p redirections, respectively. Once a co-process has been started, another cannot be started until the initial co-process exits, or the co-process input has been redirected using an exec n>&p redirection. If the input of a co-process is redirected in this way, the next co-process to be started will share the output with the first co-process, unless the output of the initial co-process has been redirected using an exec n<&p redirection.
The following additional considerations apply to co-processes:
exec 3>&p; exec 3>&-
In order for co-processes to share a common output, the shell must
keep the write portion of the output pipe open. This means that the
end-of-file will not be detected until all co-processes sharing the
co-process output have exited. When they all exit, the shell closes
its copy of the pipe. This can be avoided by redirecting the output
to a numbered file descriptor (which also causes the shell to close
its copy). This behavior is slightly different from the original
Korn shell, which closes its copy of the write portion of the
co-process when the most recently started co-process exits (instead
of all sharing co-processes).Functions are defined using either Korn shell function name syntax or the Bourne/POSIX shell name() syntax. (The differences between the two forms are described later.) Functions are like .-scripts in that they are executed in the current environment. Unlike .-scripts, however, shell arguments (such as positional parameters, $1, and so on) are never visible inside them. When the shell is determining the location of a command, functions are searched after special built-in commands and before regular and non-regular built-ins, and before the PATH is searched.
An existing function can be deleted using unset -f function-name. A list of functions can be obtained using typeset +f, and the function definitions can be listed using typeset -f. autoload (which is an alias for typeset -fu) can be used to create undefined functions. When an undefined function is executed, the shell searches the path specified in the FPATH parameter for a file with the same name as the function, which, if found is read and executed. If after executing the file, the named function is found to be defined, the function is executed. Otherwise, the normal command search is continued. That is, the shell searches the regular built-in command table and PATH. If a command is not found using PATH, an attempt is made to autoload a function using FPATH (this is an undocumented feature of the original Korn shell).
Functions can have two attributes, trace and export, that can be set with typeset -ft and typeset -fx, respectively. When a traced function is executed, the shell's xtrace option is turned on for the functions duration. Otherwise, the xtrace option is turned off. The export attribute of functions is currently not used. In the original Korn shell, exported functions are visible to shell scripts that are executed.
Since functions are executed in the current shell environment, parameter assignments made inside functions are visible after the function completes. If this is not the effect you want, use the typeset command inside a function to create a local parameter. Special parameters (such as $$, $!), however, cannot be scoped in this way.
The exit status of a function is that of the last command executed in the function. A function can be made to finish immediately using the return command. This can also be used to explicitly specify the exit status.
Functions defined with the function reserved word are treated differently in the following ways from functions defined with the () notation:
The shell is intended to be POSIX compliant. In some cases, however, POSIX behavior is contrary either to the original Korn shell behavior or to user convenience. How the shell behaves in these cases is determined by the state of the posix option (set +o posix). If it is on, the POSIX behavior is followed; otherwise, it is not. The posix option is set automatically when the shell starts up if the environment contains the POSIXLY_CORRECT parameter.
The following is a list of things that are affected by the state of the posix option.
alias a='for ' i='j'
a i in 1 2; do echo i=$i j=$j; done
After evaluation of command-line arguments, redirections, and parameter assignments, the type of command is determined: a special built-in command, a function, a regular built-in command, or the name of a file to execute found using the PATH parameter. The checks are made in the above order. Special built-in commands differ from other commands in that the PATH parameter is not used to find them, an error during their execution can cause a non-interactive shell to exit, and parameter assignments that are specified before the command are kept after the command completes. In addition, if the posix option is turned off (see set command) some special commands are very special in that no field splitting, file globbing, brace expansion or tilde expansion is preformed on arguments that look like assignments. Regular built-in commands are different only in that the PATH parameter is not used to find them.
The original ksh and POSIX differ somewhat in which commands are considered special or regular. These are shown in the following tables:
POSIX special commands | ||||
---|---|---|---|---|
. | continue | exit | return | trap |
: | eval | export | set | unset |
break | exec | readonly | shift |
Additional ksh special commands | ||
---|---|---|
builtin | times | typeset |
Very Special commands (non-posix mode) | |||
---|---|---|---|
alias | readonly | set | typeset |
POSIX regular commands | ||||
---|---|---|---|---|
alias | command | fg | kill | umask |
bg | false | getopts | read | unalias |
cd | fc | jobs | true | wait |
Additional ksh regular commands | |||
---|---|---|---|
[ | let | pwd | ulimit |
User commands | |||
---|---|---|---|
echo | test | whence |
In the future, the additional ksh special and regular commands might be treated differently from the POSIX special and regular commands.
Once the type of the command has been determined, any command-line parameter assignments are performed and exported for the duration of the command.
The following describes the special and regular built-in commands:
Without arguments, alias lists all aliases and their values. For any name without a value, its value is listed. Any name with a value defines an alias (see the section on aliases).
The -x option sets the export attribute of an alias, or, if no names are given, lists the aliases with the export attribute (exporting an alias currently has no effect).
The -t option indicates that tracked aliases are to be listed/set (values specified on the command line are ignored for tracked aliases). The -r option indicates that all tracked aliases are to be reset.
The -d causes directory aliases, which are used in tilde expansion, to be listed or set (see the section on tilde expansion).
If the -v option is given, instead of executing cmd, information about what would be executed is given, and the same is done for arg1 ...). For special and regular built-in commands and functions, their names are simply printed. For aliases, a command that defines them is printed. For commands found by searching the PATH parameter, the full path of the command is printed. If no command is be found, (that is, the path search fails), nothing is printed and command exits with a non-zero status. The -V option is like the -v option, except it is more verbose.
The options are provided for compatibility with Berkeley Software Distribution (BSD) shell scripts: -n suppresses the trailing newline, -e enables backslash interpretation (a no-op, since this is normally done), and -E suppresses backslash interpretation.
If no arguments are given, any input/output (I/O) redirection is permanent and the shell is not replaced. Any file descriptors greater than two that are opened or duplicated in this way are not made available to other executed commands (that is, commands that are not built-in to the shell).
If no parameters are specified, the names of all parameters with the export attribute are printed one per line unless the -p option is used, in which case export commands defining all exported parameters, including their values, are printed.
Each time getopts is invoked, it places the next option in the shell parameter name and the index of the next argument to be processed in the shell parameter OPTIND. If the option was introduced with a +, the option placed in name is prefixed with a +. When an option requires an argument, getopts places it in the shell parameter OPTARG. When an illegal option or a missing option argument is encountered, a question mark or a colon is placed in name (indicating an illegal option or missing argument, respectively), and OPTARG is set to the option character that caused the problem. An error message is also printed to standard error if optstring does not begin with a colon.
When the end of the options is encountered, getopts exits with a non-zero exit status. Options end at the first (non-option argument) argument that does not start with a -, or when a -- argument is encountered.
Option parsing can be reset by setting OPTIND to 1 (this is done automatically whenever the shell or a shell procedure is invoked).
It should be noted that changing the value of the shell parameter OPTIND to a value other than 1, or parsing different sets of arguments without resetting OPTIND can lead to unexpected results.
The -R option is used to emulate, to some degree, the BSD echo command, which does not process \ sequences unless the -e option is given. As above, the -n option suppresses the trailing newline.
To display a prompt, append a question mark and the prompt to the first parameter (for example, read nfoo?'number of foos: ').
The -un and -p options cause input to be read from file descriptor n or the current co-process, respectively. (See the section on co-processes for more information.) If the -s option is used, input is saved to the history file.
If no parameters are specified, the names of all parameters with the read-only attribute are printed one per line, unless the -p option is used, in which case readonly commands defining all read-only parameters, including their values, are printed.
Option letter | Long name | Description |
---|---|---|
-A | Sets the elements of the array parameter name to arg ...; if -A is used, the array is reset (that is, emptied) first. If +A is used, the first N elements are set (where N is the number of args), and the rest are left untouched. | |
-a | allexport | All new parameters are created with the export attribute. |
-b | notify | Print job notification messages asynchronously instead of just before the prompt. Only used if job control is enabled (-m). |
-C | noclobber | Prevent > redirection from overwriting existing files (>| must be used to force an overwrite). |
-e | errexit | Exit (after executing the ERR trap) as soon as an error occurs or a command fails (that is, exits with a non-zero status). This does not apply to commands whose exit status is explicitly tested by a shell construct, such as if, until, while, &&, or || statements. |
-f | noglob | Do not expand file-name patterns. |
-h | trackall | Create tracked aliases for all executed commands (see the section on aliases). On by default for non-interactive shells. |
-i | interactive | Enable interactive mode. This can only be set/unset when the shell is invoked. |
-k | keyword | Parameter assignments are recognized anywhere in a command. |
-l | login | The shell is a login shell. This can only be set/unset when the shell is invoked (see the section on shell startup). |
-m | monitor | Enable job control (default for interactive shells). |
-n | noexec | Do not execute any commands. Useful for checking the syntax of scripts (ignored if interactive). |
-p | privileged | Set automatically if, when the shell starts, the read user identifier (UID) or group identifier (GID) does not match the effective UID or GID, respectively. (See the section on shell startup for a description of what this means.) |
-r | restricted | Enable restricted mode. This option can only be used when the shell is invoked. (See the section on shell startup for a description of what this means.) |
-s | stdin | If used when the shell is invoked, commands are read from standard input; set automatically if the shell is invoked with no arguments. When -s is used in the set command, it causes the specified arguments to be sorted before assigning them to the positional parameters (or to array name, if -A is used). |
-u | nounset | Referencing of an unset parameter is treated as an error unless one of the -, +, or = modifiers is used. |
-v | verbose | Write shell input to standard error as it is read. |
-x | xtrace | Print commands and parameter assignments when they are executed, preceded by the value of PS4. |
-X | markdirs | Mark directories with a trailing / during file-name generation. |
bgnice | Background jobs are run with lower priority. | |
braceexpand | Enable brace expansion (also known as alternation). | |
cmd_intitle | Displays the current command line in the title bar of the terminal window. | |
emacs | Enable BRL emacs-like command-line editing (interactive shells only); see the section on emacs interactive input line editing. | |
gmacs | Enable gmacs-like (Gosling emacs) command-line editing (interactive shells only); currently identical to emacs editing except that transpose (^T) acts slightly differently. | |
ignoreeof | The shell will not exit on when it reaches the end of the file; exit must be used. | |
nohup | Do not kill running jobs with a HUP signal when a login shell exists. Currently set by default, but this will change in the future to be compatible with the original Korn shell (which does not have this option, but does send the HUP signal). | |
nolog | No effect in the original Korn shell; this prevents function definitions from being stored in the history file. | |
physical | Causes the cd and pwd commands to use 'physical' (the file system's) .. directories instead of 'logical' directories (that is, the shell handles .., which allows the user to be oblivious of symlink links to directories). Clear by default. Setting this option does not effect the current value of the PWD parameter; only the cd command changes PWD. See the cd and pwd commands for more details. | |
posix | Enable posix mode. See POSIX mode. | |
vi | Enable vi-like command-line editing (interactive shells only). | |
viraw | No effect. In most implementations of the Korn shell, unless the viraw option was set, the vi command-line mode would let the tty driver do the work until ESC (^[) was entered. The Interix ksh(1) utility is always in viraw mode. | |
vi-esccomplete | In vi command-line editing, do command / file-name completion when escape (^[) is entered in command mode. | |
vi-show8 | Prefix characters with the eighth-bit set with 'M-'. If this option is not set, characters in the range 128-160 are printed as is, which can cause problems. | |
vi-tabcomplete | In vi command-line editing, do command / file-name completion when tab (^I) is entered in insert mode. |
These options can also be used upon invocation of the shell. The current set of options (with single-letter names) can be found in the parameter -. set -o with no option name will list all the options, including whether each is on or off; set +o will print the long names of all options that are currently on.
Remaining arguments, if any, are positional parameters and are assigned, in order, to the positional parameters (such as 1 and 2). If options are ended with --, and there are no remaining arguments, all positional parameters are cleared. If no options or arguments are given, the values of all names are printed. For unknown historical reasons, a lone - option is treated specially: it clears both the -x and -v options.
test evaluates the expression and returns zero status if true, 1 status if false, and greater than 1 if there was an error. It is usually used as the condition command of if and while statements. The following basic expressions are available:
Expression | Description |
---|---|
str | str has non-zero length. There is the potential for problems if str turns out to be an operator (for example, -r ). It is generally better to use a test like [ X"str" != X ] instead (double quotes are used in case str contains spaces or file-globbing characters). |
-r file | file exists and is readable. |
-w file | file exists and is writable. |
-x file | file exists and is executable. |
-a file | file exists. (This option is obsolete and might disappear in future versions.) |
-e file | file exists. |
-f file | file is a regular file. |
-d file | file is a directory. |
-c file | file is a character special device. |
-b file | file is a block special device. |
-p file | file is a named pipe. |
-u file | file's mode has setuid bit set. |
-g file | file's mode has setgid bit set. |
-k file | file's mode has sticky bit set. |
-s file | file is not empty. |
-O file | file's owner is the shell's effective UID. |
-G file | file's group is the shell's effective GID |
-h file | file is a symbolic link. |
-L file | file is a symbolic link. |
-S file | file is a socket. |
-o option | Shell option is set (see set command for list of options). As a non-standard extension, if the option starts with a !, the test is negated; the test always fails if option does not exist (thus [-o foo -o -o !foo ] returns true only if option foo exists). The total number of operands to the [ command determines whether -o is interpreted as the option test or the OR binary operator. |
file -nt file | First file is newer than second file. |
file -ot file | First file is older than second file. |
file -ef file | First file is the same file as second file. |
-t fd | File descriptor is a tty device. Default value of fd is 1. |
string | string is not empty. |
-z string | string is empty. |
-n string | string is not empty. |
string = string | Strings are equal. |
string == string | Strings are equal. |
string != string | Strings are not equal. |
number -eq number | Numbers compare equal. |
number -ne number | Numbers compare not equal. |
number -ge number | Numbers compare greater than or equal. |
number -gt number | Numbers compare greater than. |
number -le number | Numbers compare less than or equal. |
number -lt number | Numbers compare less than. |
The above basic expressions, in which unary operators have precedence over binary operators, can be combined with the following operators (listed in increasing order of precedence):
Operator | Description |
---|---|
expr -o expr | Logical or |
expr -a expr | Logical and |
! expr | Logical not |
(expr) | Grouping |
On operating systems not supporting /dev/fd/n devices (where n is a file descriptor number), the test command will attempt to fake it for all tests that operate on files (except the -e test). That is, [ -w /dev/fd/2 ] tests to determine whether file descriptor 2 is writable.
Note that some special rules are applied (courtesy of POSIX) if the number of arguments to test or [ ... ] is less than five: if leading ! arguments can be stripped so that only one argument remains, a string length test is performed (again, even if the argument is a unary operator); if leading ! arguments can be stripped so that three arguments remain and the second argument is a binary operator, the binary operation is performed (even if first argument is a unary operator, including an unstripped !).
It is a common mistake to use if [ $foo = bar ], which fails if parameter foo is null or unset, if it has embedded spaces (that is, IFS characters), or if it is a unary operator like ! or -n. Use tests like if [ "X$foo" = Xbar ] instead.
With no arguments, trap lists, as a series of trap commands, the current state of the traps that have been set since the shell started.
The original Korn shell's DEBUG trap and the handling of ERR and EXIT traps in functions are not yet implemented.
If name arguments are given, the attributes of the named parameters are set (-) or cleared (+). Values for parameters may optionally be specified. If typeset(1) is used inside a function, any newly created parameters are local to the function.
When -f is used, typeset(1) operates on the attributes of functions. As with parameters, if no names are given, functions are listed with their values (that is, definitions) unless options are introduced with +, in which case only the function names are reported.
-Ln | Left-justify attribute. n specifies the field width. If n is not specified, the current width of a parameter (or the width of its first assigned value) is used. Leading white space (and zeros, if used with the -Z option) is stripped. If necessary, values are either truncated or space padded to fit the field width. |
-Rn | Right-justify attribute. n specifies the field width. If n is not specified, the current width of a parameter (or the width of its first assigned value) is used. Trailing white space is stripped. If necessary, values are either stripped of leading characters or space padded to make them fit the field width. |
-Zn | Zero fill attribute. If not combined with -L, this is the same as -R, except zero padding is used instead of space padding. |
-in | Integer attribute. n specifies the base to use when displaying the integer (if not specified, the base given in the first assignment is used). Parameters with this attribute can be assigned values containing arithmetic expressions. |
-U | Unsigned integer attribute. Integers are printed as unsigned values (only useful when combined with the -i option). This option is not in the original Korn shell. |
-f | Function mode. Display or set functions and their attributes instead of parameters. |
-l | Lowercase attribute. All uppercase characters in values are converted to lowercase. (In the original Korn shell, this parameter meant 'long integer' when used with the -i option). |
-r | Read-only attribute. Parameters with the this attribute cannot be assigned to or unset. Once this attribute is set, it cannot be turned off. |
-t | Tag attribute. Has no meaning to the shell; provided for application use. For functions, -t is the trace attribute. When functions with the trace attribute are executed, the xtrace (-x) shell option is temporarily turned on. |
-u | Uppercase attribute. All lowercase characters in values are
converted to uppercase. (In the original Korn shell, this parameter
meant 'unsigned integer' when used with the -i option, which
meant uppercase letters would never be used for bases greater than
10. See the -U option).
For functions, -u is the undefined attribute. See the section on functions for the implications of this. |
-x | Export attribute. Parameters (or functions) are placed in the environment of any executed commands. Exported functions are not yet implemented. |
Symbolic masks are like those used by chmod(1): [ugoa]{{=+-}{rwx}*}+[,...], in which the first group of characters is the who part, the second group is the op part, and the last group is the perm part. The who part specifies which part of the umask is to be modified. The letters have the following meanings:
The op part indicates how the who permissions are to be modified:
The perm part specifies which permissions are to be set, added, or removed:
When symbolic masks are used, they describe which permissions can be made available (as opposed to octal masks, in which a set bit means the corresponding bit is to be cleared). For example: 'ug=rwx,o=' sets the mask so files will not be readable, writable, or executable by 'others', and is equivalent (on most systems) to the octal mask '07'.
If no jobs are specified, wait waits for all currently running jobs (if there are any) to finish and exits with a zero status. If job monitoring is enabled, the completion status of jobs is printed (this is not the case when jobs are explicitly specified).
Job control refers to the shell's ability to monitor and control jobs, which are processes or groups of processes created for commands or pipelines. At a minimum, the shell keeps track of the status of the background (that is, asynchronous) jobs that currently exist. This information can be displayed using the jobs command. If job control is fully enabled (using set -m or set -o monitor), as it is for interactive shells, the processes of a job are placed in their own process group, foreground jobs can be stopped by typing the suspend character from the terminal (normally ^Z), jobs can be restarted in either the foreground or background, using the fg and bg commands, respectively, and the state of the terminal is saved or restored when a foreground job is stopped or restarted, respectively.
Only commands that create processes (such as asynchronous commands, subshell commands, and non-built-in, non-function commands) can be stopped; commands like read cannot be stopped.
When a job is created, it is assigned a job number. For interactive shells, this number is printed inside [..], followed by the process identifiers (PID) of the processes in the job when an asynchronous command is run. A job can be referred to in bg, fg, jobs, kill and wait commands either by the PID of the last process in the command pipeline (as stored in the $! parameter) or by prefixing the job number with a percent sign (%). Other percent sequences can also be used to refer to jobs:
%+ | The most recently stopped job, or, if there are no stopped jobs, the oldest running job. |
%%, % | Same as %+. |
%- | The job that would be the %+ job, if the later did not exist. |
%n | The job with job number n. |
%?string | The job containing the string string (an error occurs if multiple jobs are matched). |
%string | The job starting with string string (an error occurs if multiple jobs are matched). |
When a job changes state (for example, a background job finishes or foreground job is stopped), the shell prints the following status information: [number] flag status command where:
When an attempt is made to exit the shell while there are jobs in the stopped state, the shell warns the user that there are stopped jobs and does not exit. If another attempt is immediately made to exit the shell, the stopped jobs are sent a HUP signal and the shell exits. Similarly, if the nohup option is not set, and there are running jobs when an attempt is made to exit a login shell, the shell warns the user and does not exit. If another attempt is immediately made to exit the shell, the running jobs are sent a HUP signal and the shell exits.
When the emacs option is set, interactive input line editing is enabled. This mode is slightly different from the emacs mode in the original Korn shell, and the eighth bit is stripped in emacs mode. In this mode, various editing commands (typically bound to one or more control characters) cause immediate actions without waiting for a newline. Several editing commands are bound to particular control characters when the shell is invoked. These bindings can be changed using the following commands:
The specified editing command is bound to the given string, which should consist of a control character (which may be written using caret notation ^X), optionally preceded by one of the two prefix characters. Future input of the string will cause the editing command to be immediately invoked. Although only two prefix characters (usually ESC and ^X) are supported, some multi-character sequences can be supported. The following binds the arrow keys on an ANSI terminal, or xterm (these are in the default bindings). Some escape sequences, however, will not work quite this well:
bind '^[['=prefix-2
bind '^XA'=up-history
bind '^XB'=down-history
bind '^XC'=forward-char
bind '^XD'=backward-char
The following is a list of available editing commands. Each description starts with the name of the command, an n if the command can be prefixed with a count, and any keys the command is bound to by default (written using caret notation; for example, ASCII ESC character is written as ^[). A count prefix for a command is entered using the sequence ^[n, where n is a sequence of 1 or more digits; unless otherwise specified, if a count is omitted, it defaults to 1. Note that editing-command names are used only with the bind command. Furthermore, many editing commands are useful only on terminals with a visible cursor. The default bindings were chosen to resemble corresponding EMACS key bindings. The users' tty characters (such as ERASE) are bound to reasonable substitutes and override the default bindings.
The vi command-line editor in ksh has basically the same commands as the vi editor (see vi(1)), with the following exceptions:
Note that the ^X stands for control-X; also <esc>, <space> and <tab> are used for escape, space and tab, respectively.
As in vi, there are two modes: insert mode and command mode. In insert mode, most characters are simply put in the buffer at the current cursor position as they are typed. Some characters are treated specially, however. In particular, the following characters are taken from current tty settings (see stty(1)) and have their usual meaning (normal values are in parentheses): kill (^U), erase (^?), werase (^W), eof (^D), intr (^C) and quit (^\).
In addition, the following characters are also treated specially in insert mode:
^H | Erases previous character. |
^V | Literal next: the next character typed is not treated specially (can be used to insert the characters being described here). |
^J ^M | End of line: the current line is read, parsed, and executed by the shell. |
<esc> | Puts the editor in command mode. |
^E | Command and file-name enumeration. |
^F | Command and file-name completion. If used twice in a row, the list of possible completions is displayed; if used a third time, the completion is undone. |
^X | Command and file-name expansion. |
<tab> | Optional file-name and command completion (see ^F), enabled with set -o vi-tabcomplete. |
If a line is longer that the screen width (see COLUMNS parameter), a >, + or < character is displayed in the last column indicating that there are more characters after, before and after, or before the current position, respectively. The line is scrolled horizontally as necessary.
In command mode, each character is interpreted as a command. Characters that either do not correspond to commands, are illegal combinations of commands, or are commands that cannot be carried out, all cause beeps. In the following command descriptions, a n indicates that the command can be prefixed by a number (for example, 10l moves right 10 characters); if no number prefix is used, n is assumed to be 1 unless otherwise specified. The term 'current position' refers to the position between the cursor and the character preceding the cursor. A 'word' is a sequence of letters, digits, and underscore characters, or a sequence of non-letter, non-digit, non-underscore, non-white-space characters (for example, ab2*&^ contains two words), and a 'big word' is a sequence of non-white-space characters.
The following commands are not in, or are different from, the normal vi file editor:
The following commands control movement within the line in vi edit mode.
The following commands control movement between command lines in vi edit mode.
The following commands edit the command line.
This shell is based on the public domain 7th edition Bourne shell clone by Charles Forsyth and parts of the BRL shell by Doug A. Gwyn, Doug Kingston, Ron Natalie, Arnold Robbins, Lou Salkind and others. The first release was created by Eric Gisin, and it was subsequently maintained by John R. MacMillan (chance!john@sq.sq.com), and Simon J. Gerraty (sjg@zen.void.oz.au). The current maintainer is Michael Rendell (michael@cs.mun.ca). The CONTRIBUTORS file in the source distribution contains a more complete list of people and their part in the shell's development.
By default, Interix does not execute files with the set-user-ID (setuid) or set-group-ID (setgid) mode bit set for security reasons. If an attempt is made to execute such a file, the ENOSETUID error is returned. For more information and and instructions for enabling execution of files with these mode bits set, see The superuser account and appropriate privileges in Windows Services for UNIX Help.
awk(1)
sh(1)
csh(1)
ed(1)
getconf(1)
sed(1)
stty(1)
vi(1)
dup(2)
exec(2)
getgid(2)
getuid(2)
open(2)
pipe(2)
wait(2)
getopt(3)
rand(3)
signal(2)
system(3)
The KornShell Command and Programming Language Morris Bolsky and David Korn, 1989, ISBN 0-13-516972-0.
UNIX Shell Programming Stephen G. Kochan, Patrick H. Wood, Hayden.
IEEE Standard for information Technology Portable Operating System Interface (POSIX) Part 2: Shell and Utilities" , IEEE Inc, 1993, ISBN 1-55937-255-9.