mksh (1) - Linux Manuals
mksh: MirBSD Korn shell
NAME
mksh sh - MirBSD Korn shell
SYNOPSIS
-words [-+abCefhiklmnprUuvXx [-T /dev/ttyCn | - ] ] [-+o option ] [-c string | -s | file [argument ... ] ]builtin-name [argument ... ]
DESCRIPTION
is a command interpreter intended for both interactive and shell script use. Its command language is a superset of the shC shell language and largely compatible to the original Korn shell.I'm an Android user, so what's mksh?
mksh is a UNIX shell / command interpreter, similar to COMMAND.COM or CMD.EXE which has been included with Android Open Source Project for a while now. Basically, it's a program that runs in a terminal (console window), takes user input and runs commands or scripts, which it can also be asked to do by other programs, even in the background. Any privilege pop-ups you might be encountering are thus not mksh issues but questions by some other program utilising it.Invocation
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
- 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 Sx 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 effective 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 Sx 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:
- The cd Po and Ic chdir Pc command is disabled.
- The SHELL ENV and PATH parameters cannot be changed.
- Command names can't be specified with absolute or relative paths.
- The -p option of the built-in command command can't be used.
- 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 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 Sx 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 Po `<' `>' `|' `;' , `(' , `)' , and `&' Pc . 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 Sx Input/output redirection below); `|' is used to create pipelines; `|&' is used to create co-processes (see Sx 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 Sx 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 Sx Substitution below); ``' introduces an old-style command substitution (see Sx Substitution below); `~' begins a directory expansion (see Sx Tilde expansion below); `{' and `}' delimit csh(1)Ns-style alterations (see Sx Brace expansion below); and finally, `*' , `?' , and `[' are used in file name generation (see Sx 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 Sx Parameters below), input/output redirections (see Sx 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 Sx Command execution below). Note that all command constructs 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 status 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, unless the pipefail option is set (see there). All commands of a pipeline are executed in separate subshells; this is allowed by POSIX but differs from both variants of AT&T System 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 Qq left-associative . For example, both of these commands will print only Qq 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 Sx 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 Sx 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 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; } }
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 elif s 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 Po PS3: normally `#?
' Pc . A number corresponding to one of the enumerated 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 Sx 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 Sx Functions below). Whitespace (space or tab) after name will be ignored most of the time.
- function name () { list ; }
- The same as name () (bash ism ) The function keyword is ignored.
- time [-p ] [pipeline ]
- The Sx Command execution section describes the time reserved word.
- (( expression ))
- The arithmetic expression expression is evaluated; equivalent to ``let expression'' (see Sx Arithmetic expressions and the let command, below).
- Bq Bq
expression - Similar to the test and [ ... ] commands (described later), with the following exceptions:
- Field splitting and file name generation are not performed on arguments.
- The -a (AND) and -o (OR) operators are replaced with `&&' and `||' respectively.
- Operators (e.g. `-f ' `=' `!' must be unquoted.
-
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 ]]
-
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 System ksh or GNU bash style escapes are translated. These include `\a' , `\b' , `\f' , `\n' , `\r' , `\t' , `\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 character.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 (`\0###' ) hexadecimal sequences `\x##' are limited to none up to two hexadecimal digits ``#'' both octal and hexadecimal sequences convert to raw octets; `\#' , where # is none of the above, translates to \# (backslashes are retained).
Backslash expansion in the C style mode slightly differs: octal sequences `\###' must have no digit zero prefixing the one up to three octal digits ``#'' and yield raw octets; hexadecimal sequences `\x#*' greedily eat up as many hexadecimal digits ``#'' as they can and terminate with the first non-hexadecimal digit; these translate a Unicode codepoint to UTF-8. The sequence `\c#' , where ``#'' is any octet, translates to Ctrl-# (which basically means, `\c?' becomes DEL, everything else is bitwise ANDed with 0x1F). Finally, `\#' , where # is none of the above, translates to # (has the backslash trimmed), even if it is a newline.
Aliases
There are two types of aliases: normal command aliases and tracked aliases. Command aliases are normally used as a short hand for a long or often used command. The shell expands command aliases (i.e. substitutes the alias name for its value) when it reads the first word of a command. An expanded alias is re-processed 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. Aliases are specifically an interactive feature: while they do happen to work in scripts and on the command line in some cases, aliases are expanded during lexing, so their use must be in a separate command tree from their definition; otherwise, the alias will not be found. Noticeably, command lists (separated by semicolon, in command substitutions also by newline) may be one same parse tree.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' login='exec login' nameref='typeset -n' 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 see 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 (i.e. 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), make(1), mv(1), pr(1), rm(1), sed(1), sh(1), vi(1), and who(1).
Substitution
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 (deprecated) ` command ` or (executed in the current environment) ${Another variant of substitution are the valsubs (value substitutions) ${| command ;} which are also executed in the current environment, like funsubs, but share their I/O with the parent; instead, they evaluate to whatever the, initially empty, expression-local variable REPLY is set to within the command s
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 octets which are used to break a string up into several words; any octets from the set space, tab, and newline that appear in the IFS octets are called ``IFS whitespace'' Sequences of one or more IFS whitespace octets, in combination with zero or one non- IFS whitespace octets, delimit a field. As a special case, leading and trailing IFS whitespace and trailing IFS non-whitespace are stripped (i.e. no leading or trailing empty field is created by it); leading non- IFS whitespace does create an empty field.
Example: If IFS is set to ``<space>:'' and VAR is set to ``<space>A<space>:<space><space>B::D'' the substitution for $VAR results in four fields: `A' `B' `(an empty field),' and `D' Note that 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.
Also, note that the field splitting applies only to the immediate result of the substitution. Using the previous example, the substitution for $VAR:E results in the fields: `A' `B' `,' and `D:E' not `A' `B' `,' `D' and `E' This behavior is POSIX compliant, but incompatible with some other shell implementations which do field splitting on the word which contained the substitution or use IFS as a general whitespace delimiter.
The results of substitution are, unless otherwise specified, also subject to brace expansion and file name expansion (see the relevant sections below).
A command substitution is replaced by the output generated by the specified
command which is run in a subshell.
For
$( command )
and
${
Note that some shells do not use a recursive parser for command substitutions,
leading to failure for certain constructs; to be portable, use as workaround
`x=$(cat)'
<<EOF
(or the newline-keeping
`x=<<EOF'
extension) instead to merely slurp the string.
St -p1003.1
recommends to use case statements of the form
`x=$(case'
$foo in (bar) echo $bar ;; (*) echo $baz ;; esac)
instead, which would work but not serve as example for this portability issue.
Arithmetic substitutions are replaced by the value of the specified expression.
For example, the command
print $((2+3*4))
displays 14.
See
Sx Arithmetic expressions
for a description of an expression.
Parameter substitutions take the form
$ name
${ name }
or
${ name [expr ]
where
name
is a parameter name.
Substitution of all array elements with
${ name [*]}
and
${ name [@]}
works equivalent to $* and $@ for positional parameters.
If substitution is performed on a parameter
(or an array parameter element)
that is not set, a null string is substituted unless the
nounset
option
Po set -o nounset
or
set -u
Pc is set, in which case an error occurs.
Parameters can be assigned values in a number of ways.
First, the shell implicitly sets some parameters like
`#'
,
`PWD'
,
and
`$'
;
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,
FOO=bar
sets the parameter
``FOO''
to
``bar''
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; see below for the implications of this).
Note that both the parameter name and the
`='
must be unquoted for the shell to recognise a parameter assignment.
The construct
FOO+=baz
is also recognised; the old and new values are immediately concatenated.
The fourth way of setting a parameter is with the
export
global
readonly
and
typeset
commands; see their descriptions in the
Sx Command execution
section.
Fifth,
for
and
select
loops set parameters as well as the
getopts
read
and
set -A
commands.
Lastly, parameters can be assigned values using assignment operators
inside arithmetic expressions (see
Sx Arithmetic expressions
below) or using the
${ name = value }
form of the parameter substitution (see below).
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(7))
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:
Note that, for all of the above,
word
is actually considered quoted, and special parsing rules apply.
The parsing rules also differ on whether the expression is double-quoted:
word
then uses double-quoting rules, except for the double quote itself
(`'
)
and the closing brace, which, if backslash escaped, gets quote removal applied.
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 (if
name
is an array, its element #0 will be substituted in a scalar context):
Note that
pattern
may need extended globbing pattern
(@(...))
single
('...')
or double
(...)
quote escaping unless
-o sh
is set.
The following special parameters are implicitly set by the shell and cannot be
set directly using assignments:
The following parameters are set and/or used by the shell:
Note
If
HISTFILE
isn't set, no history file is used.
This is different from
AT&T System
ksh
Note
This parameter is not imported from the environment when the shell is
started.
The default prompt is
`$
The
distribution comes with a sample
dot.mkshrc
containing a sophisticated example, but you might like the following one
(note that ${HOSTNAME:=$(hostname)} and the
root-vs-user distinguishing clause are (in this example) executed at
PS1
assignment time, while the $USER and $PWD are escaped
and thus will be evaluated each time a prompt is displayed):
Note that since the command-line editors try to figure out how long the prompt
is (so they know how far it is to the edge of the screen), escape codes in
the prompt tend to mess things up.
You can tell the shell not to count certain
sequences (such as escape codes) by prefixing your prompt with a
character (such as Ctrl-A) followed by a carriage return and then delimiting
the escape codes with this character.
Any occurences of that character in the prompt are not printed.
By the way, don't blame me for
this hack; it's derived from the original
ksh88(1),
which did print the delimiter character so you were out of luck
if you did not have any non-printing characters.
Since Backslashes and other special characters may be
interpreted by the shell, to set
PS1
either escape the backslash itself,
or use double quotes.
The latter is more practical.
This is a more complex example,
avoiding to directly enter special characters (for example with
^V
in the emacs editing mode),
which embeds the current working directory,
in reverse video
(colour would work, too)
in the prompt string:
Due to a strong suggestion from David G. Korn,
now also supports the following form:
In parameter assignments
(such as those preceding a simple-command or those occurring
in the arguments of
alias
export
global
readonly
and
typeset )
tilde expansion is done after any assignment
(i.e. after the equals sign)
or after an unquoted colon
(`:'
)
login names are also delimited by colons.
The home directory of previously expanded login names are cached and re-used.
The
alias -d
command may be used to list, change, and add to this cache (e.g.
alias -d fac=/usr/local/facilities; cd ~fac/bin )
The expressions are expanded to
N
words, each of which is the concatenation of
prefix
str i
and
suffix
(e.g.
``a{c,b{X,Y},d}e''
expands to four words:
``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 (e.g.
{}
and
{foo}
are not expanded).
Brace expansion is carried out after parameter substitution
and before file name generation.
Note that complicated globbing, especially with alternatives,
is slow; using separate comparisons may (or may not) be faster.
Note that
mksh
Po and Nm pdksh Pc
never matches
`.'
and
`..'
but
AT&T System
ksh
Bourne
sh
and GNU
bash
do.
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
`/'
If no
marker
is given, the here document ends at the next
<<
and substitution will be performed.
If
marker
is only a set of either single
``''''
or double
`'
quotes with nothing in between, the here document ends at the next empty line
and substitution will not be performed.
In any of the above redirections, the file descriptor that is redirected
(i.e. standard input or standard output)
can be explicitly given by preceding the
redirection with a number (portably, only a single digit).
Parameter, command, and arithmetic
substitutions, tilde substitutions, and (if the shell is interactive)
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 expanded file name generation characters is used.
Note
that in restricted shells, redirections which can create files cannot be used.
For simple-commands, redirections may appear anywhere in the command; for
compound-commands
Po if
statements, etc.
Pc ,
any redirections must appear at the end.
Redirections are processed after
pipelines are created and in the order they are given, so the following
will print an error with a line number prepended to it:
File descriptors created by input/output redirections are private to the
Korn shell, but passed to sub-processes if
-o posix
or
-o sh
is set.
Expressions are calculated using signed arithmetic and the
Vt mksh_ari_t
type (a 32-bit signed integer), unless they begin with a sole
`#'
character, in which case they use
Vt mksh_uari_t
Po a 32-bit unsigned integer Pc .
Expressions may contain alpha-numeric parameter identifiers, array references,
and integer constants and may be combined with the following C operators
(listed and grouped in increasing order of precedence):
Unary operators:
Binary operators:
Ternary operators:
Grouping operators:
Integer constants and expressions are calculated using an exactly 32-bit
wide, signed or unsigned, type with silent wraparound on integer overflow.
Integer constants may 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.
Additionally, base-16 integers may be specified by prefixing them with
`0x'
(case-insensitive)
in all forms of arithmetic expressions, except as numeric arguments to the
test
built-in command.
Prefixing numbers with a sole digit zero
(`0'
)
leads to the shell interpreting it as base-8 integer in
posix
mode
only
historically, (pd)ksh has never done so either anyway,
and it's unsafe to do that, but POSIX demands it nowadays.
As a special
mksh
extension, numbers to the base of one are treated as either (8-bit
transparent) ASCII or Unicode codepoints, depending on the shell's
utf8-mode
flag (current setting).
The
AT&T System
ksh93
syntax of
``'x'''
instead of
``1#x''
is also supported.
Note that NUL bytes (integral value of zero) cannot be used.
An unset or empty parameter evaluates to 0 in integer context.
In Unicode mode, raw octets are mapped into the range EF80..EFFF as in
OPTU-8, which is in the PUA and has been assigned by CSUR for this use.
If more than one octet in ASCII mode, or a sequence of more than one
octet not forming a valid and minimal CESU-8 sequence is passed, the
behaviour is undefined (usually, the shell aborts with a parse error,
but rarely, it succeeds, e.g. on the sequence C2 20).
That's why you should always use ASCII mode unless you know that the
input is well-formed UTF-8 in the range of 0000..FFFD.
The operators are evaluated as follows:
Some notes concerning co-processes:
An existing function may 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
The
autoload
command (which is an alias for
typeset -fu
may 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 (i.e. the shell searches the regular built-in command table and
PATH )
Note that 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''
which 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 function's duration.
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 desired effect, the
typeset
command can be used inside a function to create a local parameter.
Note that
AT&T System
ksh93
uses static scoping (one global scope, one local scope per function)
and allows local variables only on Korn style functions, whereas
mksh
uses dynamic scoping (nested scopes of varying locality).
Note that special parameters (e.g.
$$ , $!
can't 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 may 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:
In the future, the following differences may also be added:
The original
ksh
and POSIX differ somewhat in which commands are considered
special or regular.
POSIX special built-in utilities:
. , : , break , continue
eval , exec , exit , export
readonly , return , set , shift
times , trap , unset
Additional
commands keeping assignments:
builtin , global , typeset , wait
Builtins that are not special:
[ , alias , bg , bind
cat , cd , command , echo
false , fc , fg , getopts
jobs , kill , let , mknod
print , pwd , read , realpath
rename , sleep , test , true
ulimit , umask , unalias , whence
Once the type of 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:
When listing aliases, one of two formats is used.
Normally, aliases are listed as
name = value
where
value
is quoted.
If options were preceded with
`+'
,
or a lone
`+'
is given on the command line, only
name
is printed.
The
-d
option causes directory aliases which are used in tilde expansion to be
listed or set (see
Sx Tilde expansion
above).
If the
-p
option is used, each alias is prefixed with the string
``alias
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
-x
option sets
(+x clears
)
the export attribute of an alias, or, if no names are given, lists the aliases
with the export attribute (exporting an alias has no effect).
Control characters may be written using caret notation
i.e. ^X represents Ctrl-X.
Note that although only two prefix characters (usually ESC and ^X)
are supported, some multi-character sequences can be supported.
The following default bindings show how the arrow keys, the home, end and
delete key on a BSD wsvt25, xterm-xfree86 or GNU screen terminal are bound
(of course some escape sequences won't work out quite this nicely):
If the
-L
option (logical path) is used or if the
physical
option isn't set (see the
set
command below), references to
`..'
in
dir
are relative to the path used to get to the directory.
If the
-P
option (physical path) is used or if the
physical
option is set,
`..'
is relative to the filesystem directory tree.
The
PWD
and
OLDPWD
parameters are updated to reflect the current and old working directory,
respectively.
If the
-e
option is set for physical filesystem traversal, and
PWD
could not be set, the exit code is 1; greater than 1 if an
error occurred, 0 otherwise.
If the
-p
option is given, a default search path is used instead of the current value of
PATH
the actual value of which is system dependent.
If the
-v
option is given, instead of executing
cmd
information about what would be executed is given (and the same is done for
arg ... )
For special and regular built-in commands and functions, their names are simply
printed; for aliases, a command that defines them is printed; and for commands
found by searching the
PATH
parameter, the full path of the command is printed.
If no command is found
(i.e. 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.
Prints its arguments (separated by spaces) followed by a newline, to the
standard output.
The newline is suppressed if any of the arguments contain the
backslash sequence
`\c'
See the
print
command below for a list of other backslash sequences that are recognised.
The options are provided for compatibility with
BSD shell scripts.
The
-n
option suppresses the trailing newline,
-e
enables backslash interpretation (a no-op, since this is normally done), and
-E
suppresses backslash interpretation.
If the
posix
or
sh
option is set or this is a direct builtin call, only the first argument
is treated as an option, and only if it is exactly
``-n
''
Backslash interpretation is disabled.
If no command is given except for I/O redirection, the I/O redirection is
permanent and the shell is
not replaced.
Any file descriptors greater than 2 which are opened or
dup(2)Ns'd
in this way are not made available to other executed commands (i.e. commands
that are not built-in to the shell).
Note that the Bourne shell differs here;
it does pass these file descriptors on.
If no parameters are specified, all parameters with the export attribute
set are printed one per line; either their names, or, if a
`-'
with no option letter is specified, name=value pairs, or, with
-p
export
commands suitable for re-entry.
Each time
getopts
is invoked, it places the next option in the shell parameter
name
and the index of the argument to be processed by the next call to
getopts
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.
Furthermore, if
optstring
does not begin with a colon, a question mark is placed in
name
OPTARG
is unset, and an error message is printed to standard error.
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).
Warning: Changing the value of the shell parameter
OPTIND
to a value other than 1, or parsing different sets of arguments without
resetting
OPTIND
may lead to unexpected results.
See
mknod(8)
for further information.
The
-R
option is used to emulate, to some degree, the
BSD echo(1)
command which does not process
`\'
sequences unless the
-e
option is given.
As above, the
-n
option suppresses the trailing newline.
The options are as follows:
If the input is a terminal, both the
-N
and
-n
options set it into raw mode;
they read an entire file if -1 is passed as
z
argument.
The first parameter may have a question mark and a string appended to it, in
which case the string is used as a prompt (printed to standard error before
any input is read) if the input is a
tty(4)
(e.g.
read nfoo?'number of foos: ' )
If no input is read or a timeout occurred,
read
exits with a non-zero status.
Another handy set of tricks:
If
read
is run in a loop such as
while read foo; do ...; done
then leading whitespace will be removed (IFS) and backslashes processed.
You might want to use
while IFS= read -r foo; do ...; done
for pristine I/O.
Similarily, when using the
-a
option, use of the
-r
option might be prudent; the same applies for:
The inner loop will be executed in a subshell and variable changes
cannot be propagated if executed in a pipeline:
Use co-processes instead:
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.
An alternative syntax for the command
set -A foo -- a b c
which is compatible to
GNU
bash
and also supported by
AT&T System
ksh93
is:
foo=(a b c); foo+=(d e)
Another
AT&T System
ksh93
and
GNU
bash
extension allows specifying the indices used for
arg ...
(from the above example, a b c
)
like this:
set -A foo -- [0]=a [1]=b [2]=c
or
foo=([0]=a [1]=b [2]=c)
which can also be written
foo=([0]=a b c)
because indices are incremented automatically.
When
-s
is used with 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).
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 and 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 (i.e. $1, $2, etc.).
If options end 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
-v
and
-x
options.
The following basic expressions are available:
The above basic expressions, in which unary operators have precedence over
binary operators, may be combined with the following operators (listed in
increasing order of precedence):
Note that a number actually may be an arithmetic expression, such as
a mathematical term or the name of an integer variable:
Note that some special rules are applied (courtesy of
Px ) if the number of arguments to
test
or inside the brackets
[ ... ]
is less than five: if leading
`!'
arguments can be stripped such that only one to three arguments remain,
then the lowered comparison is executed; (thanks to XSI) parentheses
\( ... \)
lower four- and three-argument forms to two- and one-argument forms,
respectively; three-argument forms ultimately prefer binary operations,
followed by negation and parenthesis lowering; two- and four-argument forms
prefer negation followed by parenthesis; the one-argument form always implies
-n
Note
A common mistake is to use
``if [ $foo = bar ]''
which fails if parameter
``foo''
is
NULL
or unset, if it has embedded spaces (i.e.
IFS
octets), or if it is a unary operator like
`!'
or
`-n
'
Use tests like
``if [ x$foo = xbar ]''
instead, or the double-bracket operator
``if [[ $foo = bar ]]''
or, to avoid pattern matching (see
[[
above):
``if [[ $foo = $bar ]]''
The
[[ ... ]]
construct is not only more secure to use but also often faster.
If the
-p
option is given the output is slightly longer:
It is an error to specify the
-p
option unless
pipeline
is a simple command.
Simple redirections of standard error do not affect the output of the
time
command:
Times for the first command do not go to
``afile''
but those of the second command do.
There are two special signals:
EXIT
(also known as 0) which is executed when the shell is about to exit, and
ERR
which is executed after an error occurs (an error is something that would cause
the shell to exit if the
-e
or
errexit
option were set --- see the
set
command above).
EXIT
handlers are executed in the environment of the last executed command.
Note
that for non-interactive shells, the trap handler cannot be changed for signals
that were ignored when the shell started.
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.
Note that the output of
trap
cannot be usefully piped to another process (an artifact of the fact that
traps are cleared when subprocesses are created).
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.
For
name [*]
the change affects the entire array, and no value may be specified.
If
typeset
is used inside a function, any parameters specified are localised.
This is not done by the otherwise identical
global
Note
This means that
's global
command is
not
equivalent to other programming languages' as it does not allow a
function called from another function to access a parameter at truly
global scope, but only prevents putting an accessed one into local scope.
When
-f
is used,
typeset
operates on the attributes of functions.
As with parameters, if no
name
arguments are given,
functions are listed with their values (i.e. definitions) unless
options are introduced with
`+'
,
in which case only the function names are reported.
For functions,
-t
is the trace attribute.
When functions with the trace attribute are executed, the
xtrace
(-x
)
shell option is temporarily turned on.
For functions,
-u
is the undefined attribute.
See
Sx Functions
above for the implications of this.
If any of the
-i
-L
-l
-R
-U
-u
or
-Z
options are changed, all others from this set are cleared,
unless they are also given on the same command line.
As far as
ulimit
is concerned, a block is 512 bytes.
Symbolic masks are like those used by
chmod(1).
When used, they describe what permissions may 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
``007''
The exit status is non-zero if any of the parameters have the read-only
attribute set, zero otherwise.
If no jobs are specified,
wait
waits for all currently running jobs (if 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).
Note that only commands that create processes (e.g. asynchronous commands,
subshell commands, and non-built-in, non-function commands) can be stopped;
commands like
read
cannot be.
When a job is created, it is assigned a job number.
For interactive shells, this number is printed inside
``[..]''
followed by the process IDs of the processes in the job when an asynchronous
command is run.
A job may be referred to in the
bg
fg
jobs
kill
and
wait
commands either by the process ID 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:
When a job changes state (e.g. a background job finishes or foreground job is
stopped), the shell prints the following status information:
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
SIGHUP
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
SIGHUP
signal and the shell exits.
In these editing modes, if a line is longer than the screen width (see the
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.
Completed lines are pushed into the history, unless they begin with an
IFS octet or IFS white space, or are the same as the previous line.
The following is a list of available editing commands.
Each description starts with the name of the command,
suffixed with a colon;
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
e.g. the ASCII ESC character is written as ^[.
These control sequences are not case sensitive.
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 user's
tty(4)
characters (e.g.
ERASE
are bound to
reasonable substitutes and override the default bindings.
The vi command-line editor in
has basically the same commands as the
vi(1)
editor with the following exceptions:
Like
vi(1),
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; however, some characters are
treated specially.
In particular, the following characters are taken from current
tty(4)
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 to
the above, the following characters are also treated specially in insert mode:
In command mode, each character is interpreted as a command.
Characters that
don't correspond to commands, are illegal combinations of commands, or are
commands that can't be carried out, all cause beeps.
In the following command descriptions, an
[n
]
indicates the command may be prefixed by a number (e.g.
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, and non-whitespace characters (e.g.
``ab2*&^''
contains two words) and a
``big-word''
is a sequence of non-whitespace characters.
Special
vi commands:
The following commands are not in, or are different from, the normal vi file
editor:
Intra-line movement commands:
Inter-line movement commands:
Edit commands
Miscellaneous vi commands
Note: On Android,
/system/etc/
contains the system and suid profile.
has a different scope model from
AT&T System
ksh
which leads to subtile differences in semantics for identical builtins.
This can cause issues with a
nameref
to suddenly point to a local variable by accident; fixing this is hard.
The parts of a pipeline, like below, are executed in subshells.
Thus, variable assignments inside them fail.
Use co-processes instead.
mksh
provides a consistent set of 32-bit integer arithmetics, both signed
and unsigned, with defined wraparound and sign of the result of a modulo
operation, even (defying POSIX) on 64-bit systems.
If you require 64-bit integer arithmetics, use
lksh (legacy mksh)
instead, but be aware that, in POSIX, it's legal for the OS to make
print $((2147483647 + 1))
delete all files on your system, as it's Undefined Behaviour.
This document attempts to describe
mksh R46
and up,
compiled without any options impacting functionality, such as
MKSH_SMALL
when not called as
/bin/sh
which, on some systems only, enables
set -o sh
automatically (whose behaviour differs across targets),
for an operating environment supporting all of its advanced needs.
Please report bugs in
to the
MirOS
mailing list at
Aq miros-mksh [at] mirbsd.org
or in the
#!/bin/mksh
(or #ksh
)
IRC channel at
irc.freenode.net
(Port 6697 SSL, 6667 unencrypted)
or at:
https://launchpad.net/mksh
http://docsrv.sco.com:507/en/man/html.C/sh.C.html
https://www.mirbsd.org/ksh-chan.htm
x=$(case $foo in bar) echo $bar ;; *) echo $baz ;; esac)
# above fails to parse on old shells; below is the workaround
x=$(eval $(cat)) <<"EOF"
case $foo in bar) echo $bar ;; *) echo $baz ;; esac
EOF
Parameters
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
below, or a letter followed by zero or more letters or digits
Po `_'
counts as a letter
Pc .
The latter form can be treated as arrays by appending an array index of the
form
[expr
]
where
expr
is an arithmetic expression.
Array indices in
are limited to the range 0 through 4294967295, inclusive.
That is, they are a 32-bit unsigned integer.
If used
outside of double quotes, parameters are separate words (which are subjected
to word splitting); if used within double quotes, parameters are separated
by the first character of the
IFS
parameter (or the empty string if
IFS
is
NULL )
PS1='${USER:=$(id -un)}'"@${HOSTNAME:=$(hostname)}:\$PWD $(
if (( USER_ID )); then print \$; else print \#; fi) "
x=$(print \\001)
PS1="$x$(print \\r)$x$(tput smso)$x\$PWD$x$(tput rmso)$x> "
PS1=$'\1\r\1\e[7m\1$PWD\1\e[0m\1> '
Tilde expansion
Tilde expansion which is done in parallel with parameter substitution, is done
on words starting with an unquoted
`~'
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.
Brace expansion (alteration)
Brace expressions take the following form:
prefix { str1 ,...,
strN } suffix
File name patterns
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 meaning:
Input/output redirection
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 and/or standard output 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:
Arithmetic expressions
Integer arithmetic expressions can be used with the
let
command, inside $((..)) expressions, inside array references (e.g.
name Bq expr
as numeric arguments to the
test
command, and as the value of an assignment to an integer parameter.
+ - ! ~ ++ --
,
= += -= *= /= %= <<<= >>>= <<= >>= &= ^= |=
||
&&
|
^
&
== !=
< <= > >=
<<< >>> << >>
+ -
* / %
?: (precedence is immediately higher than assignment)
( )
Co-processes
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 can't
be started until the co-process exits, or until the co-process's input has been
redirected using an
exec n >&p
redirection.
If a co-process's input 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.
Functions
Functions are defined using either Korn shell
function function-name
syntax or the Bourne/POSIX shell
function-name ()
syntax (see below for the difference between the two forms).
Functions are like
.-scripts
(i.e. scripts sourced using the
`.'
built-in)
in that they are executed in the current environment.
However, unlike
.-scripts
shell arguments (i.e. positional parameters $1, $2, etc.)
are never visible inside them.
When the shell is determining the location of a command, functions
are searched after special built-in commands, before builtins and the
PATH
is searched.
Command execution
After evaluation of command-line arguments, redirections, and parameter
assignments, the type of command is determined: a special built-in command,
a function, a normal builtin, 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.
Regular built-in commands are different only in that the
PATH
parameter is not used to find them.
bind '^X'=prefix-2
bind '^[['=prefix-2
bind '^XA'=up-history
bind '^XB'=down-history
bind '^XC'=forward-char
bind '^XD'=backward-char
bind '^X1~'=beginning-of-line
bind '^X7~'=beginning-of-line
bind '^XH'=beginning-of-line
bind '^X4~'=end-of-line
bind '^X8~'=end-of-line
bind '^XF'=end-of-line
bind '^X3~'=delete-char-forward
find . -type f -print0 | \
while IFS= read -d '' -r filename; do
print -r -- "found <${filename#./}>"
done
bar | baz | while read foo; do ...; done
bar | baz |&
while read -p foo; do ...; done
exec 3>&p; exec 3>&-
expr -o expr Logical OR.
expr -a expr Logical AND.
! expr Logical NOT.
( expr ) Grouping.
x=1; [ "x" -eq 1 ] evaluates to true
"0m0.00s real 0m0.00s user 0m0.00s system"
real 0.00
user 0.00
sys 0.00
$ time sleep 1 2>afile
$ { time sleep 1; } 2>afile
0m0.00s 0m0.00s
0m0.00s 0m0.00s
Job control
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 (i.e.
asynchronous) jobs that currently exist; this information can be displayed
using the
jobs
commands.
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, and the state of the terminal is saved or restored when a foreground
job is stopped or restarted, respectively.
Interactive input line editing
The shell supports three modes of reading command lines from a
tty(4)
in an interactive session, controlled by the
emacs
gmacs
and
vi
options (at most one of these can be set at once).
The default is
emacs
Editing modes can be set explicitly using the
set
built-in.
If none of these options are enabled,
the shell simply reads lines using the normal
tty(4)
driver.
If the
emacs
or
gmacs
option is set, the shell allows emacs-like editing of the command; similarly,
if the
vi
option is set, the shell allows vi-like editing of the command.
These modes are described in detail in the following sections.
Emacs editing mode
When the
emacs
option is set, interactive input line editing is enabled.
Warning: This mode is
slightly different from the emacs mode in the original Korn shell.
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
bind
command.
Vi editing mode
Note:
The vi command-line editing mode is orphaned, yet still functional.
FILES
AUTHORS
The MirBSD Korn Shell
is developed by
An Thorsten Glaser Aq tg [at] mirbsd.org
and currently maintained as part of The MirOS Project.
This shell is based upon the Public Domain Korn SHell.
The developer of mksh recognises the efforts of the pdksh authors,
who had dedicated their work into Public Domain, our users, and
all contributors, such as the Debian and OpenBSD projects.
See the documentation, CVS, and web site for details.
CAVEATS
only supports the Unicode BMP (Basic Multilingual Plane).
foo | bar | read baz # will not change $baz
foo | bar |& read -p baz # will, however, do so
BUGS
Suspending (using ^Z) pipelines like the one below will only suspend
the currently running part of the pipeline; in this example,
``fubar''
is immediately printed on suspension (but not later after an
fg )
$ /bin/sleep 666 && echo fubar
SEE ALSO
awk(1),
cat(1),
ed(1),
getopt(1),
sed(1),
sh(1),
stty(1),
dup(2),
execve(2),
getgid(2),
getuid(2),
mknod(2),
mkfifo(2),
open(2),
pipe(2),
rename(2),
wait(2),
getopt(3),
nl_langinfo3,
setlocale(3),
signal(3),
system(3),
tty(4),
shells(5),
environ(7),
script(7),
utf-87,
mknod(8)