MKSH(1) BSD General Commands Manual MKSH(1)
NAME
mksh, sh -- MirBSD Korn shell
SYNOPSIS
mksh [-+abCefhiklmnprUuvXx] [-T /dev/ttyCn | -] [-+o option] [-c string | -s | file [argument ...]]
builtin-name [argument ...]
DESCRIPTION
mksh is a command interpreter intended for both interactive and shell script use. Its command language is a superset of the sh(C) shell lan-
guage and largely compatible to the original Korn shell.
Most builtins can be called directly, for example if a link points from its name to the shell; not all make sense, have been tested or work
at all though.
The options are as follows:
-c string mksh will execute the command(s) contained in string.
-i Interactive shell. A shell is ``interactive'' if this option is used or if both standard input and standard error are attached to
a tty(4). An interactive shell has job control enabled, ignores the SIGINT, SIGQUIT, and SIGTERM signals, and prints prompts
before reading input (see the PS1 and PS2 parameters). It also processes the ENV parameter or the mkshrc file (see below). For
non-interactive shells, the trackall option is on by default (see the set command below).
-l Login shell. If the basename the shell is called with (i.e. argv[0]) starts with '-' or if this option is used, the shell is
assumed to be a login shell; see Startup files below.
-p Privileged shell. A shell is ``privileged'' if this option is used or if the real user ID or group ID does not match the effec-
tive user ID or group ID (see getuid(2) and getgid(2)). Clearing the privileged option causes the shell to set its effective user
ID (group ID) to its real user ID (group ID). For further implications, see Startup files.
-r Restricted shell. A shell is ``restricted'' if this option is used. The following restrictions come into effect after the shell
processes any profile and ENV files:
o The cd (and chdir) command is disabled.
o The SHELL, ENV, and PATH parameters cannot be changed.
o Command names can't be specified with absolute or relative paths.
o The -p option of the built-in command command can't be used.
o Redirections that create files can't be used (i.e. '>', '>|', '>>', '<>').
-s The shell reads commands from standard input; all non-option arguments are positional parameters.
-T tty Spawn mksh on the tty(4) device given. Superuser only. If tty is a dash, detach from controlling terminal (daemonise) instead.
In addition to the above, the options described in the set built-in command can also be used on the command line: both [-+abCefhkmnuvXx] and
[-+o option] can be used for single letter or long options, respectively.
If neither the -c nor the -s option is specified, the first non-option argument specifies the name of a file the shell reads commands from.
If there are no non-option arguments, the shell reads commands from the standard input. The name of the shell (i.e. the contents of $0) 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 basename the shell was called with (i.e. argv[0]) is used.
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.
Startup files
For the actual location of these files, see FILES. A login shell processes the system profile first. A privileged shell then processes the
suid profile. A non-privileged login shell processes the user profile next. A non-privileged interactive shell checks the value of the ENV
parameter after subjecting it to parameter, command, arithmetic and tilde ('~') substitution; if unset or empty, the user mkshrc profile is
processed; otherwise, if a file whose name is the substitution result exists, it is processed; non-existence is silently ignored.
Command syntax
The shell begins parsing its input by removing any backslash-newline combinations, then breaking it into words. Words (which are sequences
of characters) are delimited by unquoted whitespace characters (space, tab, and newline) or meta-characters ('<', '>', '|', ';', '(', ')',
and '&'). Aside from delimiting words, spaces and tabs are ignored, while newlines usually delimit commands. The meta-characters are used
in building the following tokens: '<', '<&', '<<', '<<<', '>', '>&', '>>', '&>', etc. are used to specify redirections (see Input/output
redirection below); '|' is used to create pipelines; '|&' is used to create co-processes (see Co-processes below); ';' is used to separate
commands; '&' is used to create asynchronous pipelines; '&&' and '||' are used to specify conditional execution; ';;', ';&' and ';|' are used
in case statements; '(( .. ))' is used in arithmetic expressions; and lastly, '( .. )' is used to create subshells.
Whitespace and meta-characters can be quoted individually using a backslash (''), or in groups using double ('"') or single (''') quotes.
Note that 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 Quoting
below); '#', if used at the beginning of a word, introduces a comment - everything after the '#' up to the nearest newline is ignored; '$' is
used to introduce parameter, command, and arithmetic substitutions (see Substitution below); '`' introduces an old-style command substitution
(see Substitution below); '~' begins a directory expansion (see Tilde expansion below); '{' and '}' delimit csh(1)-style alterations (see
Brace expansion below); and finally, '*', '?', and '[' are used in file name generation (see File name patterns below).
As words and tokens are parsed, the shell builds commands, of which there are two basic types: simple-commands, typically programmes 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 Parameters below), input/output redirections (see Input/output
redirections below), and command words; the only restriction is that parameter assignments come before any command words. The command words,
if any, define the command that is to be executed and its arguments. The command may be a shell built-in command, a function, or an external
command (i.e. a separate executable file that is located using the PATH parameter; see Command execution below). Note that all command con-
structs have an exit status: for external commands, this is related to the status returned by wait(2) (if the command could not be found, the
exit status is 127; if it could not be executed, the exit status is 126); the exit status of other command constructs (built-in commands,
functions, compound-commands, pipelines, lists, etc.) are all well-defined and are described where the construct is described. The exit sta-
tus of a command consisting only of parameter assignments is that of the last command substitution performed during the parameter assignment
or 0 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. All commands of a
pipeline are executed in separate subshells; this is allowed by POSIX but differs from both variants of AT&T UNIX ksh, where all but the last
command were executed in subshells; see the read builtin's description for implications and workarounds. A pipeline may 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; if the original status was not 0, the complemented status will be 0.
Lists of commands can be created by separating pipelines by 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. Note that the '&&' and '||' operators are "left-associative". For example, both of these commands will print only
"bar":
$ false && echo foo || echo bar
$ true || echo foo && echo bar
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; see Job control below). When an asynchronous command is started
when job control is disabled (i.e. in most scripts), the command is started with signals SIGINT and SIGQUIT 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
a special kind of asynchronous process (see Co-processes below). Note that a command must follow the '&&' and '||' operators, while it need
not follow '&', '|&', or ';'. The exit status of a list is that of the last command executed, with the exception of asynchronous lists, for
which the exit status is 0.
Compound commands are created using the following reserved words. These words are only recognised if they are unquoted and if they are used
as the first word of a command (i.e. they can't be preceded by parameter assignments or redirections):
case else function then ! (
do esac if time [[ ((
done fi in until {
elif for select while }
In the following compound command descriptions, command lists (denoted as list) that are followed by reserved words must end with a semi-
colon, 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; } }
This is not valid:
$ { echo foo; echo bar }
(list)
Execute list in a subshell. There is no implicit way to pass environment changes from a subshell back to its parent.
{ list; }
Compound construct; list is executed, but not in a subshell. Note that '{' and '}' are reserved words, not meta-characters.
case word in [[(] pattern [| pat] ...) list [;; | ;& | ;| ]] ... esac
The case statement attempts to match word against a specified pattern; the list associated with the first successfully matched pattern
is executed. Patterns used in case statements are the same as those used for file name patterns except that the restrictions regarding
'.' and '/' are dropped. Note that any unquoted space before and after a pattern is stripped; any space within a pattern must be
quoted. Both the word and the patterns are subject to parameter, command, and arithmetic substitution, as well as tilde substitution.
For historical reasons, open and close braces may be used instead of in and esac e.g. case $foo { *) echo bar;; }.
The list terminators are:
';;' Terminate after the list.
';&' Fall through into the next list.
';|' Evaluate the remaining pattern-list tuples.
The exit status of a case statement is that of the executed list; if no list is executed, the exit status is zero.
for name [in word ...]; do list; done
For each word in the specified word list, the parameter name is set to the word and list is executed. If in is not used to specify a
word list, the positional parameters ($1, $2, etc.) are used instead. For historical reasons, open and close braces may be used
instead of do and done e.g. for i; { echo $i; }. The exit status of a for statement is the last exit status of list; if list is never
executed, the exit status is zero.
if list; then list; [elif list; then list;] ... [else list;] fi
If the exit status of the first list is zero, the second list is executed; otherwise, the list following the elif, if any, is executed
with similar consequences. If all the lists following the if and elifs fail (i.e. exit with non-zero status), the list following the
else is executed. The exit status of an if statement is that of non-conditional list that is executed; if no non-conditional list is
executed, the exit status is zero.
select name [in word ...]; do list; done
The select statement provides an automatic method of presenting the user with a menu and selecting from it. An enumerated list of the
specified word(s) is printed on standard error, followed by a prompt (PS3: normally '#? '). A number corresponding to one of the enu-
merated words is then read from standard input, name is set to the selected word (or unset if the selection is not valid), REPLY is set
to what was read (leading/trailing space is stripped), and list is executed. If a blank line (i.e. zero or more IFS octets) is
entered, the menu is reprinted without executing list.
When list completes, the enumerated list is printed if REPLY is NULL, the prompt is printed, and so on. This process continues until
an end-of-file is read, an interrupt is received, or a break statement is executed inside the loop. If ``in word ...'' is omitted, the
positional parameters are used (i.e. $1, $2, etc.). For historical reasons, open and close braces may be used instead of do and done
e.g. select i; { echo $i; }. The exit status of a select statement is zero if a break statement is used to exit the loop, non-zero
otherwise.
until list; do list; done
This works like while, except that the body is executed only while the exit status of the first list is non-zero.
while list; do list; done
A while is a pre-checked loop. Its body is executed as often as the exit status of the first list is zero. The exit status of a while
statement is the last exit status of the list in the body of the loop; if the body is not executed, the exit status is zero.
function name { list; }
Defines the function name (see Functions below). Note that redirections specified after a function definition are performed whenever
the function is executed, not when the function definition is executed.
name() command
Mostly the same as function (see Functions below). Whitespace (space or tab) after name will be ignored most of the time.
function name() { list; }
The same as name() (bashism). The function keyword is ignored.
time [-p] [pipeline]
The Command execution section describes the time reserved word.
(( expression ))
The arithmetic expression expression is evaluated; equivalent to ``let expression'' (see Arithmetic expressions and the let command,
below).
[[ expression ]]
Similar to the test and [ ... ] commands (described later), with the following exceptions:
o Field splitting and file name generation are not performed on arguments.
o The -a (AND) and -o (OR) operators are replaced with '&&' and '||', respectively.
o Operators (e.g. '-f', '=', '!') must be unquoted.
o Parameter, command, and arithmetic substitutions are performed as expressions are evaluated and lazy expression evaluation is used
for the '&&' and '||' operators. This means that in the following statement, $(<foo) is evaluated if and only if the file foo
exists and is readable:
$ [[ -r foo && $(<foo) = b*r ]]
o The second operand of the '!=' and '=' expressions are patterns (e.g. the comparison [[ foobar = f*r ]] succeeds). This even works
indirectly:
$ bar=foobar; baz='f*r'
$ [[ $bar = $baz ]]; echo $?
$ [[ $bar = "$baz" ]]; echo $?
Perhaps surprisingly, the first comparison succeeds, whereas the second doesn't.
Quoting
Quoting is used to prevent the shell from treating characters or words specially. There are three methods of quoting. First, '' 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 may span lines). Third, a double quote ('"') quotes all characters, except '$',
'`' and '', up to the next unquoted double quote. '$' and '`' inside double quotes have their usual meaning (i.e. parameter, command, or
arithmetic substitution) except 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.
If a single-quoted string is preceded by an unquoted '$', C style backslash expansion (see below) is applied (even single quote characters
inside can be escaped and do not terminate the string then); the expanded result is treated as any other single-quoted string. If a double-
quoted string is preceded by an unquoted '$', the latter is ignored.
Backslash expansion
In places where backslashes are expanded, certain C and AT&T UNIX ksh or GNU bash style escapes are translated. These include 'a', '',
'f', '
', '
', ' ', 'U########', 'u####', and 'v'. For 'U########' and 'u####', ``#'' means a hexadecimal digit, of thich there may
be none up to four or eight; these escapes translate a Unicode codepoint to UTF-8. Furthermore, 'E' and 'e' expand to the escape charac-
ter.
In the print builtin mode, '"', ''', and '?' are explicitly excluded; octal sequences must have the none up to three octal digits ``#''
prefixed with the digit zero ('