-.\" $MirOS: src/bin/mksh/mksh.1,v 1.413 2016/08/10 18:20:05 tg Exp $
+.\" $MirOS: src/bin/mksh/mksh.1,v 1.420 2016/11/11 23:31:36 tg Exp $
.\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $
.\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
.\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always.
.\"
-.Dd $Mdocdate: August 10 2016 $
+.Dd $Mdocdate: November 11 2016 $
.\"
.\" Check which macro package we use, and do other -mdoc setup.
.\"
.Xr tty 4 .
An interactive shell has job control enabled, ignores the
.Dv SIGINT ,
-.Dv SIGQUIT ,
+.Dv SIGQUIT
and
.Dv SIGTERM
signals, and prints prompts before reading input (see the
.It
The
.Ev SHELL ,
-.Ev ENV ,
+.Ev ENV
and
.Ev PATH
parameters cannot be changed.
can't be used.
.It
Redirections that create files can't be used (i.e.\&
-.Ql \*(Gt ,
-.Ql \*(Gt\*(Ba ,
-.Ql \*(Gt\*(Gt ,
-.Ql \*(Lt\*(Gt ) .
+.Dq Li \*(Gt ,
+.Dq Li \*(Gt\*(Ba ,
+.Dq Li \*(Gt\*(Gt ,
+.Dq Li \*(Lt\*(Gt ) .
.El
.It Fl s
The shell reads commands from standard input; all non-option arguments
Unless
.Ar name
begins with an exclamation mark
-.Pq Sq \&! ,
+.Pq Ql \&! ,
this is done in a subshell and returns immediately.
If
.Ar name
is a dash
-.Pq Sq \&\- ,
+.Pq Ql \&\- ,
detach from controlling terminal (daemonise) instead.
.El
.Pp
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
+the exit status is that of the last command executed, or zero if no
command is executed.
.Ss Startup files
For the actual location of these files, see
A non-privileged interactive shell checks the value of the
.Ev ENV
parameter after subjecting it to parameter, command, arithmetic and tilde
-.Pq Sq \*(TI
+.Pq Ql \*(TI
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.
combinations, then breaking it into
.Em words .
Words (which are sequences of characters) are delimited by unquoted whitespace
-characters (space, tab, and newline) or meta-characters
+characters (space, tab and newline) or meta-characters
.Po
.Ql \*(Lt ,
.Ql \*(Gt ,
.Ql \*(Ba ,
.Ql \&; ,
.Ql \&( ,
-.Ql \&) ,
+.Ql \&)
and
.Ql &
.Pc .
usually delimit commands.
The meta-characters are used in building the following
.Em tokens :
-.Ql \*(Lt ,
-.Ql \*(Lt& ,
-.Ql \*(Lt\*(Lt ,
-.Ql \*(Lt\*(Lt\*(Lt ,
-.Ql \*(Gt ,
-.Ql \*(Gt& ,
-.Ql \*(Gt\*(Gt ,
-.Ql &\*(Gt ,
+.Dq Li \*(Lt ,
+.Dq Li \*(Lt& ,
+.Dq Li \*(Lt\*(Lt ,
+.Dq Li \*(Lt\*(Lt\*(Lt ,
+.Dq Li \*(Gt ,
+.Dq Li \*(Gt& ,
+.Dq Li \*(Gt\*(Gt ,
+.Dq Li &\*(Gt ,
etc. are used to specify redirections (see
.Sx Input/output redirection
below);
-.Ql \*(Ba
+.Dq Li \*(Ba
is used to create pipelines;
-.Ql \*(Ba&
+.Dq Li \*(Ba&
is used to create co-processes (see
.Sx Co-processes
below);
-.Ql \&;
+.Dq Li \&;
is used to separate commands;
-.Ql &
+.Dq Li &
is used to create asynchronous pipelines;
-.Ql &&
+.Dq Li &&
and
-.Ql \*(Ba\*(Ba
+.Dq Li \*(Ba\*(Ba
are used to specify conditional execution;
-.Ql ;; ,
-.Ql ;&\&
+.Dq Li \&;; ,
+.Dq Li \&;&
and
-.Ql ;\*(Ba\&
+.Dq Li \&;\*(Ba
are used in
.Ic case
statements;
-.Ql \&(( .. ))
+.Dq Li \&(( ... \&))
is used in arithmetic expressions;
and lastly,
-.Ql \&( .. \&)
+.Dq Li \&( ... \&)
is used to create subshells.
.Pp
Whitespace and meta-characters can be quoted individually using a backslash
-.Pq Sq \e ,
+.Pq Ql \e ,
or in groups using double
-.Pq Sq \&"
+.Pq Ql \&"
or single
-.Pq Dq \*(aq
+.Pq Dq Li \*(aq
quotes.
Note that the following characters are also treated specially by the
shell and must be quoted if they are to represent themselves:
.Ql \e ,
.Ql \&" ,
-.Ql \*(aq ,
+.Dq Li \*(aq ,
.Ql # ,
.Ql $ ,
.Ql \` ,
.Ql { ,
.Ql } ,
.Ql * ,
-.Ql \&? ,
+.Ql \&?
and
.Ql \&[ .
The first three of these are the above mentioned quoting characters (see
.Ql #
up to the nearest newline is ignored;
.Ql $
-is used to introduce parameter, command, and arithmetic substitutions (see
+is used to introduce parameter, command and arithmetic substitutions (see
.Sx Substitution
below);
.Ql \`
below);
and finally,
.Ql * ,
-.Ql \&? ,
+.Ql \&?
and
.Ql \&[
are used in file name generation (see
.Ic for
and
.Ic if
-statements, grouping constructs, and function definitions.
+statements, grouping constructs and function definitions.
.Pp
A simple-command consists of some combination of parameter assignments
(see
below),
input/output redirections (see
.Sx Input/output redirections
-below),
+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,
+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
.Ev PATH
parameter assignment or 0 if there were no command substitutions.
.Pp
Commands can be chained together using the
-.Ql \*(Ba
+.Dq Li \*(Ba
token to form pipelines, in which the standard output of each command but the
last is piped (see
.Xr pipe 2 )
.Ic read
builtin's description for implications and workarounds.
A pipeline may be prefixed by the
-.Ql \&!
+.Dq Li \&!
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.
.Em Lists
of commands can be created by separating pipelines by any of the following
tokens:
-.Ql && ,
-.Ql \*(Ba\*(Ba ,
-.Ql & ,
-.Ql \*(Ba& ,
+.Dq Li && ,
+.Dq Li \*(Ba\*(Ba ,
+.Dq Li & ,
+.Dq Li \*(Ba&
and
-.Ql \&; .
+.Dq Li \&; .
The first two are for conditional execution:
.Dq Ar cmd1 No && Ar cmd2
executes
only if the exit status of
.Ar cmd1
is zero;
-.Ql \*(Ba\*(Ba
+.Dq Li \*(Ba\*(Ba
is the opposite \*(en
.Ar cmd2
is executed only if the exit status of
.Ar cmd1
is non-zero.
-.Ql &&
+.Dq Li &&
and
-.Ql \*(Ba\*(Ba
+.Dq Li \*(Ba\*(Ba
have equal precedence which is higher than that of
-.Ql & ,
-.Ql \*(Ba& ,
+.Dq Li & ,
+.Dq Li \*(Ba&
and
-.Ql \&; ,
+.Dq Li \&; ,
which also have equal precedence.
Note that the
-.Ql &&
+.Dq Li &&
and
-.Ql \*(Ba\*(Ba
+.Dq Li \*(Ba\*(Ba
operators are
.Qq left-associative .
For example, both of these commands will print only
.Ed
.Pp
The
-.Ql &
+.Dq Li &
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
.Pa /dev/null
(however, redirections specified in the asynchronous command have precedence).
The
-.Ql \*(Ba&
+.Dq Li \*(Ba&
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
-.Ql &&
+.Dq Li &&
and
-.Ql \*(Ba\*(Ba
+.Dq Li \*(Ba\*(Ba
operators, while it need not follow
-.Ql & ,
-.Ql \*(Ba& ,
+.Dq Li & ,
+.Dq Li \*(Ba&
or
-.Ql \&; .
+.Dq Li \&; .
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.
.Pp
.Pp
In the following compound command descriptions, command lists (denoted as
.Em list )
-that are followed by reserved words must end with a semicolon, a newline, or
+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:
.Bd -literal -offset indent
.Ar list
is executed, but not in a subshell.
Note that
-.Ql {
+.Dq Li {
and
-.Ql }
+.Dq Li }
are reserved words, not meta-characters.
.It Xo case Ar word No in
.Oo Op \&(
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
+patterns are subject to parameter, command and arithmetic substitution, as
well as tilde substitution.
.Pp
For historical reasons, open and close braces may be used instead of
.Ic terminator Ns s
are:
.Bl -tag -width 4n
-.It Ql ;;
+.It Dq Li ;;
Terminate after the list.
-.It Ql ;&\&
+.It Dq Li \&;&
Fall through into the next list.
-.It Ql ;\*(Ba\&
+.It Dq Li \&;\*(Ba
Evaluate the remaining pattern-list tuples.
.El
.Pp
is executed.
If
.Ic in
-is not used to specify a word list, the positional parameters
-($1, $2, etc.)\&
-are used instead.
+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
.Ic do
and
.Ar word Ns (s)
is printed on standard error, followed by a prompt
.Po
-.Ev PS3: normally
-.Sq #?\ \&
+.Ev PS3 :
+normally
+.Dq Li #?\ \&
.Pc .
A number corresponding to one of the enumerated words is then read from
standard input,
.Ar list
completes, the enumerated list is printed if
.Ev REPLY
-is
-.Dv NULL ,
-the prompt is printed, and so on.
+is empty, the prompt is printed, and so on.
This process continues until an end-of-file
is read, an interrupt is received, or a
.Ic break
statement is executed inside the loop.
If
-.Dq in word ...
+.Dq in Ar 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
The arithmetic expression
.Ar expression
is evaluated; equivalent to
-.Dq let expression
+.Dq Li let \&" Ns Ar expression Ns \&"
(see
.Sx Arithmetic expressions
and the
.Fl o
.Pq OR
operators are replaced with
-.Ql &&
+.Dq Li &&
and
-.Ql \*(Ba\*(Ba ,
+.Dq Li \*(Ba\*(Ba ,
respectively.
.It
Operators (e.g.\&
-.Sq Fl f ,
-.Sq = ,
-.Sq \&! )
+.Dq Li \-f ,
+.Dq Li = ,
+.Dq Li \&! )
must be unquoted.
.It
-Parameter, command, and arithmetic substitutions are performed as expressions
+Parameter, command and arithmetic substitutions are performed as expressions
are evaluated and lazy expression evaluation is used for the
-.Ql &&
+.Dq Li &&
and
-.Ql \*(Ba\*(Ba
+.Dq Li \*(Ba\*(Ba
operators.
This means that in the following statement,
.Ic $(\*(Ltfoo)
.Ed
.It
The second operand of the
-.Sq !=
+.Dq Li !=
and
-.Sq =
+.Dq Li =
expressions are a subset of patterns (e.g. the comparison
.Ic \&[[ foobar = f*r ]]
succeeds).
.Ql \e
and the newline are stripped.
Second, a single quote
-.Pq Dq \*(aq
+.Pq Dq Li \*(aq
quotes everything up to the next single quote (this may span lines).
Third, a double quote
-.Pq Sq \&"
+.Pq Ql \&"
quotes all characters, except
.Ql $ ,
-.Ql \e ,
+.Ql \e
and
.Ql \` ,
up to the next unescaped double quote.
.Ql $
and
.Ql \`
-inside double quotes have their usual meaning (i.e. parameter, arithmetic,
+inside double quotes have their usual meaning (i.e. parameter, arithmetic
or command substitution) except no field splitting is carried out on the
results of double-quoted substitutions, and the old-style form of command
substitution has backslash-quoting for double quotes enabled.
inside a double-quoted string is followed by
.Ql \&" ,
.Ql $ ,
-.Ql \e ,
+.Ql \e
or
.Ql \` ,
only the
.Nm bash
style escapes are translated.
These include
-.Ql \ea ,
-.Ql \eb ,
-.Ql \ef ,
-.Ql \en ,
-.Ql \er ,
-.Ql \et ,
-.Ql \eU######## ,
-.Ql \eu#### ,
+.Dq Li \ea ,
+.Dq Li \eb ,
+.Dq Li \ef ,
+.Dq Li \en ,
+.Dq Li \er ,
+.Dq Li \et ,
+.Dq Li \eU######## ,
+.Dq Li \eu####
and
-.Ql \ev .
+.Dq Li \ev .
For
-.Ql \eU########
+.Dq Li \eU########
and
-.Ql \eu#### ,
+.Dq Li \eu#### ,
.Dq #
-means a hexadecimal digit, of thich there may be none up to four or eight;
+means a hexadecimal digit, of which there may be none up to four or eight;
these escapes translate a Unicode codepoint to UTF-8.
Furthermore,
-.Ql \eE
+.Dq Li \eE
and
-.Ql \ee
+.Dq Li \ee
expand to the escape character.
.Pp
In the
.Ic print
builtin mode,
-.Ql \e" ,
-.Ql \e\*(aq ,
+.Dq Li \e" ,
+.Dq Li \e\*(aq
and
-.Ql \e?
+.Dq Li \e?
are explicitly excluded;
octal sequences must have the none up to three octal digits
.Dq #
prefixed with the digit zero
-.Pq Ql \e0### ;
+.Pq Dq Li \e0### ;
hexadecimal sequences
-.Ql \ex##
+.Dq Li \ex##
are limited to none up to two hexadecimal digits
.Dq # ;
both octal and hexadecimal sequences convert to raw octets;
-.Ql \e# ,
+.Dq Li \e# ,
where # is none of the above, translates to \e# (backslashes are retained).
.Pp
Backslash expansion in the C style mode slightly differs: octal sequences
-.Ql \e###
+.Dq Li \e###
must have no digit zero prefixing the one up to three octal digits
.Dq #
and yield raw octets; hexadecimal sequences
-.Ql \ex#*
+.Dq Li \ex#*
greedily eat up as many hexadecimal digits
.Dq #
as they can and terminate with the first non-hexadecimal digit;
these translate a Unicode codepoint to UTF-8.
The sequence
-.Ql \ec# ,
+.Dq Li \ec# ,
where
.Dq #
is any octet, translates to Ctrl-# (which basically means,
-.Ql \ec?
+.Dq Li \ec?
becomes DEL, everything else is bitwise ANDed with 0x1F).
Finally,
-.Ql \e# ,
+.Dq Li \e# ,
where # is none of the above, translates to # (has the backslash trimmed),
even if it is a newline.
.Ss Aliases
.Xr rm 1 ,
.Xr sed 1 ,
.Xr sh 1 ,
-.Xr vi 1 ,
+.Xr vi 1
and
.Xr who 1 .
.Ss 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.
+substitution: parameter, command and arithmetic.
Parameter substitutions,
which are described in detail in the next section, take the form
.Pf $ Ns Ar name
The
.Ev 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
+into several words; any octets from the set space, tab and newline that
appear in the
.Ev IFS
octets are called
Example: If
.Ev IFS
is set to
-.Dq \*(Ltspace\*(Gt: ,
+.Dq Li \*(Ltspace\*(Gt:
and VAR is set to
-.Dq \*(Ltspace\*(GtA\*(Ltspace\*(Gt:\*(Ltspace\*(Gt\*(Ltspace\*(GtB::D ,
+.Dq Li \*(Ltspace\*(GtA\*(Ltspace\*(Gt:\*(Ltspace\*(Gt\*(Ltspace\*(GtB::D ,
the substitution for $VAR results in four fields:
-.Sq A ,
-.Sq B ,
-.Sq
-(an empty field),
-and
-.Sq D .
+.Dq Li A ,
+.Dq Li B ,
+.Dq
+(an empty field) and
+.Dq Li D .
Note that if the
.Ev IFS
parameter is set to the empty string, no field splitting is done;
-if it is unset, the default value of space, tab, and newline is used.
+if it is unset, the default value of space, tab and newline is used.
.Pp
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:
-.Sq A ,
-.Sq B ,
-.Sq ,
+.Dq Li A ,
+.Dq Li B ,
+.Dq
and
-.Sq D:E ,
+.Dq Li D:E ,
not
-.Sq A ,
-.Sq B ,
-.Sq ,
-.Sq D ,
+.Dq Li A ,
+.Dq Li B ,
+.Dq ,
+.Dq Li D
and
-.Sq E .
+.Dq Li 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
.Ql \e
followed by any of
.Ql $ ,
-.Ql \` ,
+.Ql \`
or
.Ql \e
is stripped (as is
.Pp
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
-.Ql x=$(cat) \*(Lt\*(Lt"EOF"
+.Dq Li x=$(cat) \*(Lt\*(Lt\eEOF
(or the newline-keeping
-.Ql x=\*(Lt\*(Lt"EOF"
+.Dq Li x=\*(Lt\*(Lt\eEOF
extension) instead to merely slurp the string.
.St -p1003.1
-recommends to use case statements of the form
-.Ql "x=$(case $foo in (bar) echo $bar ;; (*) echo $baz ;; esac)"
+recommends using case statements of the form
+.Li "x=$(case $foo in (bar) echo $bar ;; (*) echo $baz ;; esac)"
instead, which would work but not serve as example for this portability issue.
.Bd -literal -offset indent
x=$(case $foo in bar) echo $bar ;; *) echo $baz ;; esac)
# above fails to parse on old shells; below is the workaround
-x=$(eval $(cat)) \*(Lt\*(Lt"EOF"
+x=$(eval $(cat)) \*(Lt\*(Lt\eEOF
case $foo in bar) echo $bar ;; *) echo $baz ;; esac
EOF
.Ed
.Pp
Parameter substitutions take the form
.Pf $ Ns Ar name ,
-.Pf ${ Ns Ar name Ns } ,
+.Pf ${ Ns Ar name Ns }
or
.Sm off
.Pf ${ Ar name Oo Ar expr Oc }
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
+that is not set, an empty string is substituted unless the
.Ic nounset
option
-.Po
-.Ic set Fl o Ic nounset
-or
-.Ic set Fl u
-.Pc
+.Pq Ic set Fl u
is set, in which case an error occurs.
.Pp
Parameters can be assigned values in a number of ways.
First, the shell implicitly sets some parameters like
-.Ql # ,
-.Ql PWD ,
+.Dq Li # ,
+.Dq Li PWD
and
-.Ql $ ;
+.Dq Li $ ;
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,
.Ic FOO=bar
sets the parameter
-.Dq FOO
+.Dq Li FOO
to
-.Dq bar ;
+.Dq Li 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
The fourth way of setting a parameter is with the
.Ic export ,
.Ic global ,
-.Ic readonly ,
+.Ic readonly
and
.Ic typeset
commands; see their descriptions in the
.Ic select
loops set parameters as well as the
.Ic getopts ,
-.Ic read ,
+.Ic read
and
.Ic set Fl A
commands.
.Sm on
If
.Ar name
-is set and not
-.Dv NULL ,
+is set and not empty,
it is substituted; otherwise,
.Ar word
is substituted.
.Sm on
If
.Ar name
-is set and not
-.Dv NULL ,
+is set and not empty,
.Ar word
is substituted; otherwise, nothing is substituted.
.Sm off
.Sm on
If
.Ar name
-is set and not
-.Dv NULL ,
+is set and not empty,
it is substituted; otherwise, it is assigned
.Ar word
and the resulting value of
.Sm on
If
.Ar name
-is set and not
-.Dv NULL ,
+is set and not empty,
it is substituted; otherwise,
.Ar word
is printed on standard error (preceded by
.Ar name : )
and an error occurs (normally causing termination of a shell script, function,
-or script sourced using the
-.Sq \&.
+or a script sourced using the
+.Dq Li \&.
built-in).
If
.Ar word
is omitted, the string
-.Dq parameter null or not set
+.Dq Li parameter null or not set
is used instead.
-Currently a bug, if
-.Ar word
-is a variable which expands to the null string, the
-error message is also printed.
.El
.Pp
Note that, for all of the above,
The parsing rules also differ on whether the expression is double-quoted:
.Ar word
then uses double-quoting rules, except for the double quote itself
-.Pq Sq \&"
+.Pq Ql \&"
and the closing brace, which, if backslash escaped, gets quote removal applied.
.Pp
In the above modifiers, the
.Ql \&:
can be omitted, in which case the conditions only depend on
.Ar name
-being set (as opposed to set and not
-.Dv NULL ) .
+being set (as opposed to set and not empty).
If
.Ar word
-is needed, parameter, command, arithmetic, and tilde substitution are performed
+is needed, parameter, command, arithmetic and tilde substitution are performed
on it; if
.Ar word
is not needed, it is not evaluated.
The number of positional parameters if
.Ar name
is
-.Ql * ,
-.Ql @ ,
+.Dq Li * ,
+.Dq Li @
or not specified; otherwise the length
.Pq in characters
of the string value of parameter
.Pf %% Ar pattern No }
.Xc
.Sm on
-Like ${..#..} substitution, but it deletes from the end of the value.
+Like ${...#...} substitution, but it deletes from the end of the value.
Cannot be applied to a vector.
.Pp
.Sm off
.It Ev \&#
The number of positional parameters ($1, $2, etc.).
.It Ev \&$
-The PID of the shell, or the PID of the original shell if it is a subshell.
+The PID of the shell or, if it is a subshell, the PID of the original shell.
Do
.Em NOT
use this mechanism for generating temporary file names; see
.It Ev \&?
The exit status of the last non-asynchronous command executed.
If the last command was killed by a signal,
-.Ic $?\&
+.Ic \&$?
is set to 128 plus the signal number, but at most 255.
.It Ev 0
The name of the shell, determined as follows:
.It Ev 1 No .. Ev 9
The first nine positional parameters that were supplied to the shell, function,
or script sourced using the
-.Sq \&.
+.Dq Li \&.
built-in.
Further positional parameters may be accessed using
.Pf ${ Ar number Ns } .
.Ev IFS
parameter (or the empty string if
.Ev IFS
-is
-.Dv NULL ) .
+is unset.
.It Ev @
Same as
.Ic $* ,
unless it is used inside double quotes, in which case a separate word is
generated for each positional parameter.
If there are no positional parameters, no word is generated.
-.Ic $@
+.Ic \&"$@"
can be used to access arguments, verbatim, without losing
-.Dv NULL
-arguments or splitting arguments with spaces.
+empty arguments or splitting arguments with spaces (IFS, actually).
.El
.Pp
The following parameters are set and/or used by the shell:
Note that if
.Ev CDPATH
is set and does not contain
-.Sq \&.
+.Dq Li \&.
or an empty string element, the current directory is not searched.
Also, the
.Ic cd
.Xr stty 1
is non-zero and sane enough (minimum is 12x3); similar for
.Ev LINES .
-This parameter is used by the interactive line editing modes, and by the
+This parameter is used by the interactive line editing modes and by the
.Ic select ,
-.Ic set Fl o ,
+.Ic set Fl o
and
.Ic kill Fl l
commands to format information columns.
formatted as decimal
.Va tv_sec
followed by a dot
-.Pq Sq \&.
+.Pq Ql \&.
and
.Va tv_usec
padded to exactly six decimal digits.
execute commands that
.Xr execve 2
fails to execute and which do not start with a
-.Dq #! Ns Ar shell
+.Dq Li #! Ns Ar shell
sequence.
.It Ev FCEDIT
The editor used by the
.It Ev IFS
Internal field separator, used during substitution and by the
.Ic read
-command, to split values into distinct arguments; normally set to space, tab,
+command, to split values into distinct arguments; normally set to space, tab
and newline.
See
.Sx Substitution
The previous working directory.
Unset if
.Ic cd
-has not successfully changed directories since the shell started, or if the
+has not successfully changed directories since the shell started or if the
shell doesn't know where it is.
.It Ev OPTARG
When using
.It Ev PATH
A colon (semicolon on OS/2) separated list of directories that are
searched when looking for commands and files sourced using the
-.Sq \&.
+.Dq Li \&.
command (see below).
An empty string resulting from a leading or trailing
colon, or two adjacent colons, is treated as a
-.Sq \&.
+.Dq Li \&.
(the current directory).
.It Ev PGRP
The process ID of the shell's process group leader.
The process ID of the shell's parent.
.It Ev PS1
The primary prompt for interactive shells.
-Parameter, command, and arithmetic
+Parameter, command and arithmetic
substitutions are performed, and
.Ql \&!
is replaced with the current command number (see the
A literal
.Ql \&!
can be put in the prompt by placing
-.Ql !!
+.Dq Li !!
in
.Ev PS1 .
.Pp
The default prompt is
-.Sq $\ \&
+.Dq Li $\ \&
for non-root users,
-.Sq #\ \&
+.Dq Li #\ \&
for root.
If
.Nm
is invoked by root and
.Ev PS1
does not contain a
-.Sq #
+.Ql #
character, the default value will be used even if
.Ev PS1
already exists in the environment.
Since Backslashes and other special characters may be
interpreted by the shell, to set
.Ev PS1
-either escape the backslash itself,
+either escape the backslash itself
or use double quotes.
The latter is more practical.
This is a more complex example,
.Ed
.It Ev PS2
Secondary prompt string, by default
-.Sq \*(Gt\ \& ,
+.Dq Li \*(Gt\ \& ,
used when more input is needed to complete a command.
.It Ev PS3
Prompt used by the
.Ic select
statement when reading a menu selection.
The default is
-.Sq #?\ \& .
+.Dq Li #?\ \& .
.It Ev PS4
Used to prefix commands that are printed during execution tracing (see the
.Ic set Fl x
command below).
-Parameter, command, and arithmetic substitutions are performed
+Parameter, command and arithmetic substitutions are performed
before it is printed.
The default is
-.Sq +\ \& .
+.Dq Li +\ \& .
You may want to set it to
-.Sq \&[$EPOCHREALTIME]\ \&
+.Dq Li \&[$EPOCHREALTIME]\ \&
instead, to include timestamps.
.It Ev PWD
The current working directory.
-May be unset or
-.Dv NULL
-if the shell doesn't know where it is.
+May be unset or empty if the shell doesn't know where it is.
.It Ev RANDOM
Each time
.Ev RANDOM
.It Ev TMPDIR
The directory temporary shell files are created in.
If this parameter is not
-set, or does not contain the absolute path of a writable directory, temporary
+set or does not contain the absolute path of a writable directory, temporary
files are created in
.Pa /tmp .
.It Ev USER_ID
.Ql / ,
if any, are assumed to be a login name.
If the login name is empty,
-.Ql + ,
+.Ql +
or
.Ql \- ,
the simplified value of the
.Ev HOME ,
-.Ev PWD ,
+.Ev PWD
or
.Ev OLDPWD
parameter is substituted, respectively.
.Ic alias ,
.Ic export ,
.Ic global ,
-.Ic readonly ,
+.Ic readonly
and
.Ic typeset ) ,
tilde expansion is done after any assignment
(i.e. after the equals sign)
or after an unquoted colon
-.Pq Sq \&: ;
+.Pq Ql \&: ;
login names are also delimited by colons.
.Pp
The home directory of previously expanded login names are cached and re-used.
The
.Ic alias Fl d
-command may be used to list, change, and add to this cache (e.g.\&
+command may be used to list, change and add to this cache (e.g.\&
.Ic alias \-d fac=/usr/local/facilities; cd \*(TIfac/bin ) .
.Ss Brace expansion (alternation)
Brace expressions take the following form:
.Ar N
words, each of which is the concatenation of
.Ar prefix ,
-.Ar str Ns i ,
+.Ar str Ns i
and
.Ar suffix
(e.g.\&
-.Dq a{c,b{X,Y},d}e
+.Dq Li a{c,b{X,Y},d}e
expands to four words:
-.Dq ace ,
-.Dq abXe ,
-.Dq abYe ,
+.Dq Li ace ,
+.Dq Li abXe ,
+.Dq Li abYe
and
-.Dq ade ) .
+.Dq Li 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
-.Pq Sq \&,
+.Pq Ql \&,
for expansion to occur (e.g.\&
.Ic {}
and
.Ql \&? ,
.Ql * ,
.Ql + ,
-.Ql @ ,
+.Ql @
or
.Ql \&!
characters or
-.Dq \&[..]
+.Dq Li \&[...]
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
Matches any single character.
.It \&*
Matches any sequence of octets.
-.It \&[..]
+.It \&[...]
Matches any of the octets inside the brackets.
Ranges of octets can be specified by separating two octets by a
.Ql \-
(e.g.\&
-.Dq \&[a0\-9]
+.Dq Li \&[a0\-9]
matches the letter
-.Sq a
+.Ql a
or any digit).
In order to represent itself, a
.Ql \-
.Ql \&!
appearing at the start of the list has special meaning (see below), so to
represent itself it must be quoted or appear later in the list.
-.It \&[!..]
-Like [..],
+.It \&[!...]
+Like [...],
except it matches any octet not inside the brackets.
.Sm off
.It *( Ar pattern\*(Ba No ...\*(Ba Ar pattern )
.Ic *(foo\*(Babar)
matches the strings
.Dq ,
-.Dq foo ,
-.Dq bar ,
-.Dq foobarfoo ,
+.Dq Li foo ,
+.Dq Li bar ,
+.Dq Li foobarfoo ,
etc.
.Sm off
.It +( Ar pattern\*(Ba No ...\*(Ba Ar pattern )
Example: The pattern
.Ic +(foo\*(Babar)
matches the strings
-.Dq foo ,
-.Dq bar ,
-.Dq foobar ,
+.Dq Li foo ,
+.Dq Li bar ,
+.Dq Li foobar ,
etc.
.Sm off
.It ?( Ar pattern\*(Ba No ...\*(Ba Ar pattern )
.Ic ?(foo\*(Babar)
only matches the strings
.Dq ,
-.Dq foo ,
+.Dq Li foo
and
-.Dq bar .
+.Dq Li bar .
.Sm off
.It @( Ar pattern\*(Ba No ...\*(Ba Ar pattern )
.Sm on
Example: The pattern
.Ic @(foo\*(Babar)
only matches the strings
-.Dq foo
+.Dq Li foo
and
-.Dq bar .
+.Dq Li bar .
.Sm off
.It !( Ar pattern\*(Ba No ...\*(Ba Ar pattern )
.Sm on
Examples: The pattern
.Ic !(foo\*(Babar)
matches all strings except
-.Dq foo
+.Dq Li foo
and
-.Dq bar ;
+.Dq Li bar ;
the pattern
-.Ic !(*)
+.Ic \&!(*)
matches no strings; the pattern
-.Ic !(?)*\&
+.Ic \&!(?)*
matches all strings (think about it).
.El
.Pp
.Nm mksh
.Po and Nm pdksh Pc
never matches
-.Sq \&.
+.Dq Li \&.
and
-.Sq .. ,
+.Dq Li .. ,
but
.At
.Nm ksh ,
Bourne
-.Nm sh ,
+.Nm sh
and GNU
.Nm bash
do.
.Pp
Note that none of the above pattern elements match either a period
-.Pq Sq \&.
+.Pq Ql \&.
at the start of a file name or a slash
-.Pq Sq / ,
-even if they are explicitly used in a [..] sequence; also, the names
-.Sq \&.
+.Pq Ql / ,
+even if they are explicitly used in a [...] sequence; also, the names
+.Dq Li \&.
and
-.Sq ..
+.Dq Li ..
are never matched, even by the pattern
-.Sq .* .
+.Dq Li .* .
.Pp
If the
.Ic markdirs
with a trailing
.Ql / .
.Ss 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
+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
+input is initially set to
.Pa /dev/null ,
and commands for which any of the following redirections have been specified:
.Bl -tag -width XXxxmarker
.Ar marker
contains no quoted characters, the contents of the temporary file are processed
as if enclosed in double quotes each time the command is executed, so
-parameter, command, and arithmetic substitutions are performed, along with
+parameter, command and arithmetic substitutions are performed, along with
backslash
-.Pq Sq \e
+.Pq Ql \e
escapes for
.Ql $ ,
.Ql \` ,
-.Ql \e ,
+.Ql \e
and
-.Ql \enewline ,
+.Dq Li \enewline ,
but not for
.Ql \&" .
If multiple here documents are used on the same command line, they are saved in
If
.Ar marker
is only a set of either single
-.Dq \*(aq\*(aq
+.Dq Li \*(aq\*(aq
or double
-.Sq \&""
+.Ql \&""
quotes with nothing in between, the here document ends at the next empty line
and substitution will not be performed.
.It \*(Lt\*(Lt\- Ns Ar marker
.Xc
Same as
.Ic \*(Gt\*(Ba Ns Ar file ,
-.Ic \*(Gt\*(Gt Ns Ar file ,
+.Ic \*(Gt\*(Gt Ns Ar file
or
.Ic \*(Gt& Ns Ar fd ,
followed by
(i.e. 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 (if the shell is interactive)
+Parameter, command and arithmetic
+substitutions, tilde substitutions, and, if the shell is interactive,
file name generation are all performed on the
.Ar file ,
-.Ar marker ,
+.Ar marker
and
.Ar fd
arguments of redirections.
.Ss Arithmetic expressions
Integer arithmetic expressions can be used with the
.Ic let
-command, inside $((..)) expressions, inside array references (e.g.\&
+command, inside $((...)) expressions, inside array references (e.g.\&
.Ar name Ns Bq Ar expr ) ,
as numeric arguments to the
.Ic test
.Ic let
command.
.Em Never
-use unchecked user input, e.g. from the environment, in arithmetics!
+use unchecked user input, e.g. from the environment, in an arithmetic context!
.Pp
Expressions are calculated using signed arithmetic and the
.Vt mksh_ari_t
type (a 32-bit signed integer), unless they begin with a sole
-.Sq #
+.Ql #
character, in which case they use
.Vt mksh_uari_t
.Po a 32-bit unsigned integer Pc .
.Pp
-Expressions may contain alpha-numeric parameter identifiers, array references,
+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):
.Pp
.Ar number
is a number in the specified base.
Additionally, base-16 integers may be specified by prefixing them with
-.Sq 0x
+.Dq Li 0x
.Pq case-insensitive
in all forms of arithmetic expressions, except as numeric arguments to the
.Ic test
built-in utility.
Prefixing numbers with a sole digit zero
-.Pq Sq 0
+.Pq Dq Li 0
does not cause interpretation as octal (except in POSIX mode,
as required by the standard), as that's unsafe to do.
.Pp
.At
.Nm ksh93
syntax of
-.Dq \*(aqx\*(aq
+.Dq Li \*(aqx\*(aq
instead of
-.Dq 1#x
+.Dq Li 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.
.Aq Ar expr
preserved.
For example,
-.Dq var1 *= 5 + 3
+.Dq Li var1 *= 5 + 3
is the same as specifying
-.Dq var1 = var1 * (5 + 3) .
+.Dq Li var1 = var1 * (5 + 3) .
.It \*(Ba\*(Ba
Logical OR;
the result is 1 if either argument is non-zero, 0 if not.
except that the bits shifted out at one end are shifted in
at the other end, instead of zero or sign bits.
.It + \- * /
-Addition, subtraction, multiplication, and division.
+Addition, subtraction, multiplication and division.
.It %
Remainder; the result is the symmetric remainder of the division of the left
argument by the right.
.El
.Ss Co-processes
A co-process (which is a pipeline created with the
-.Sq \*(Ba&
+.Dq Li \*(Ba&
operator) is an asynchronous process that the shell can both write to (using
.Ic print Fl p )
and read from (using
Functions are like
.Li .\(hyscripts
(i.e. scripts sourced using the
-.Sq \&.
+.Dq Li \&.
built-in)
in that they are executed in the current environment.
However, unlike
returns.
.El
.Ss Command execution
-After evaluation of command-line arguments, redirections, and parameter
+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
+a function, a normal builtin or the name of a file to execute found using the
.Ev PATH
parameter.
The checks are made in the above order.
If the
.Fl p
option is used, each alias is prefixed with the string
-.Dq alias\ \& .
+.Dq Li alias\ \& .
.Pp
The
.Fl t
inner-most
.Ic for ,
.Ic select ,
-.Ic until ,
+.Ic until
or
.Ic while
loop.
If a
.Ar file
is a single dash
-.Pq Sq -
+.Pq Dq Li \-
or absent, read from standard input.
For direct builtin calls, the
.Tn POSIX
.Ev CDPATH
is set, it lists the search path for the directory containing
.Ar dir .
-A
-.Dv NULL
-path means the current directory.
+An unset or empty path means the current directory.
If
.Ar dir
is found in any component of the
.Ev CDPATH
-search path other than the
-.Dv NULL
-path, the name of the new working directory will be written to standard output.
+search path other than an unset or empty path,
+the name of the new working directory will be written to standard output.
If
.Ar dir
is missing, the home directory
If
.Ar dir
is
-.Ql \- ,
+.Dq Li \- ,
the previous working directory is used (see the
.Ev OLDPWD
parameter).
option isn't set (see the
.Ic set
command below), references to
-.Sq ..
+.Dq Li ..
in
.Ar dir
are relative to the path used to get to the directory.
option (physical path) is used or if the
.Ic physical
option is set,
-.Sq ..
+.Dq Li ..
is relative to the filesystem directory tree.
The
.Ev PWD
respectively.
If the
.Fl e
-option is set for physical filesystem traversal, and
+option is set for physical filesystem traversal and
.Ev PWD
could not be set, the exit code is 1; greater than 1 if an
error occurred, 0 otherwise.
inner-most
.Ic for ,
.Ic select ,
-.Ic until ,
+.Ic until
or
.Ic while
loop.
standard output.
The newline is suppressed if any of the arguments contain the
backslash sequence
-.Ql \ec .
+.Dq Li \ec .
See the
.Ic print
command below for a list of other backslash sequences that are recognised.
.Ic 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
-.Dq Fl n .
+.Dq Li \-n .
Backslash interpretation is disabled.
.Pp
.It Ic eval Ar command ...
If
.Ar status
is not specified, the exit status is the current value of the
-.Ic $?\&
+.Ic \&$?
parameter.
.Pp
.It Xo
.Pp
If no parameters are specified, all parameters with the export attribute
set are printed one per line; either their names, or, if a
-.Ql \-
+.Dq Li \-
with no option letter is specified, name=value pairs, or, with
.Fl p ,
.Ic export
.Fl l ,
the selected commands are edited by the editor specified with the
.Fl e
-option, or if no
+option or, if no
.Fl e
is specified, the editor specified by the
.Ev FCEDIT
argument) argument that does not start with a
.Ql \- ,
or when a
-.Ql \-\-
+.Dq Li \-\-
argument is encountered.
.Pp
Option parsing can be reset by setting
.Pp
Warning: Changing the value of the shell parameter
.Ev OPTIND
-to a value other than 1, or parsing different sets of arguments without
+to a value other than 1 or parsing different sets of arguments without
resetting
-.Ev OPTIND ,
+.Ev OPTIND
may lead to unexpected results.
.Pp
.It global Ar ...
.No { Ar job \*(Ba pid \*(Ba pgrp No }
.Ar ...
.Xc
-Send the specified signal to the specified jobs, process IDs, or process
+Send the specified signal to the specified jobs, process IDs or process
groups.
If no signal is specified, the
.Dv TERM
.Xc
Print the signal name corresponding to
.Ar exit-status .
-If no arguments are specified, a list of all the signals, their numbers, and
-a short description of them are printed.
+If no arguments are specified, a list of all the signals with their numbers
+and a short description of each are printed.
.Pp
.It Ic let Op Ar expression ...
Each expression is evaluated (see
.Cm b
(block type device),
.Cm c
-(character type device),
+(character type device)
or
.Cm p
.Pq named pipe , Tn FIFO .
.Pp
.It Xo
.Ic print
-.Oo Fl Anprsu Ns Oo Ar n Oc \*(Ba
+.Oo Fl AclNnprsu Ns Oo Ar n Oc \*(Ba
.Fl R Op Fl en Oc
.Op Ar argument ...
.Xc
-.Ic print
-prints its arguments on the standard output, separated by spaces and
-terminated with a newline.
-The
-.Fl n
-option suppresses the newline.
-By default, certain C escapes are translated.
-These include these mentioned in
+Print the specified argument(s) on the standard output,
+separated by spaces, terminated with a newline.
+The C escapes mentioned in
.Sx Backslash expansion
above, as well as
-.Ql \ec ,
+.Dq Li \ec ,
which is equivalent to using the
.Fl n
-option.
-Backslash expansion may be inhibited with the
-.Fl r
-option.
-The
-.Fl s
-option prints to the history file instead of standard output; the
-.Fl u
-option prints to file descriptor
-.Ar n
-.Po
-.Ar n
-defaults to 1 if omitted
-.Pc ;
-and the
-.Fl p
-option prints to the co-process (see
+option, are interpreted.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl A
+Each
+.Ar argument
+is arithmetically evaluated; the character corresponding to the
+resulting value is printed.
+Empty
+.Ar argument Ns s
+separate input words.
+.It Fl c
+The output is printed columnised, line by line, similar to how the
+.Xr rs 1
+utility, tab completion, the
+.Ic kill Fl l
+built-in utility and the
+.Ic select
+statement do.
+.It Fl l
+Change the output word separator to newline.
+.It Fl N
+Change the output word and line separator to ASCII NUL.
+.It Fl n
+Do not print the trailing line separator.
+.It Fl p
+Print to the co-process (see
.Sx Co-processes
above).
-The
-.Fl A
-option prints the character corresponding to each
-.Ar argument Ns 's value .
+.It Fl r
+Inhibit backslash expansion.
+.It Fl s
+Print to the history file instead of standard output.
+.It Fl u Op Ar n
+Print to the file descriptor
+.Ar n Pq defaults to 1 if omitted
+instead of standard output.
+.El
.Pp
The
.Fl R
option (physical path) is used or if the
.Ic physical
option is set, the path determined from the filesystem (by following
-.Sq ..
+.Dq Li ..
directories to the root directory) is printed.
.Pp
.It Xo
Instead of reading till end-of-line, read exactly
.Ar z
bytes.
-If EOF or a timeout occurs, a partial read is returned with exit status 1.
+Upon EOF, a partial read is returned with exit status 1.
+After timeout, a partial read is returned with an exit status as if
+.Dv SIGALRM
+were caught.
.It Fl n Ar z
Instead of reading till end-of-line, read up to
.Ar z
seconds (specified as positive decimal value with an optional fractional part).
The exit status of
.Nm read
-is 1 if the timeout occurred, but partial reads may still be returned.
+is the same as if
+.Dv SIGALRM
+were caught if the timeout occurred, but partial reads may still be returned.
.It Fl r
Normally, the ASCII backslash character escapes the special
meaning of the following character and is stripped from the input;
If
.Ar name
ends with a slash
-.Pq Sq / ,
+.Pq Ql / ,
it's also checked for existence and whether it is a directory; otherwise,
.Ic realpath
returns 0 if the pathname either exists or can be created immediately,
explicitly tested by a shell construct such as
.Ic if ,
.Ic until ,
-.Ic while ,
+.Ic while
or
.Ic \&!
statements.
.Fn nl_langinfo CODESET ,
or the
.Ev LC_ALL ,
-.Ev LC_CTYPE ,
+.Ev LC_CTYPE
or
.Ev LANG
environment variables,
locale-related environment variables changes.
.It Fl u \*(Ba Fl o Ic nounset
Referencing of an unset parameter, other than
-.Dq $@
+.Dq Li $@
or
-.Dq $* ,
+.Dq Li $* ,
is treated as an error, unless one of the
.Ql \- ,
-.Ql + ,
+.Ql +
or
.Ql =
modifiers is used.
commands to use
.Dq physical
(i.e. the filesystem's)
-.Sq ..
+.Dq Li ..
directories instead of
.Dq logical
directories (i.e. the shell handles
-.Sq .. ,
+.Dq Li .. ,
which allows the user to be oblivious of symbolic links to directories).
Clear by default.
Note that setting this option does not affect the current value of the
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
-.Sq $\- .
+.Dq Li $\- .
.Ic set Fl o
with no option name will list all the options and whether each is on or off;
.Ic set +o
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
-.Ql \-\-
+.Dq Li \-\-
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
-.Ql \-
+.Dq Li \-
option is treated specially \*(en it clears both the
.Fl v
and
The positional parameters
.Ar number Ns +1 ,
.Ar number Ns +2 ,
-etc. are renamed to
-.Sq 1 ,
-.Sq 2 ,
-etc.
+etc. are renamed to 1, 2, etc.
.Ar number
defaults to 1.
.Pp
.Ql +
.Pq no logical negation ,
for example
-.Ql \-x
+.Dq Li \-x
or
-.Ql +x
+.Dq Li +x
instead of
-.Ql xtrace .
+.Dq Li xtrace .
.It Fl p Ar file
.Ar file
is a named pipe
or inside the brackets
.Ic \&[ ... \&]
is less than five: if leading
-.Ql \&!
+.Dq Li \&!
arguments can be stripped such that only one to three arguments remain,
then the lowered comparison is executed; (thanks to XSI) parentheses
.Ic \e( ... \e)
.Pp
.Sy Note :
A common mistake is to use
-.Dq if \&[ $foo = bar \&]
+.Dq Li if \&[ $foo = bar \&]
which fails if parameter
.Dq foo
-is
-.Dv NULL
-or unset, if it has embedded spaces (i.e.\&
+is empty or unset, if it has embedded spaces (i.e.\&
.Ev IFS
-octets), or if it is a unary operator like
-.Sq \&!
+octets) or if it is a unary operator like
+.Dq Li \&!
or
-.Sq Fl n .
+.Dq Li \-n .
Use tests like
-.Dq if \&[ x\&"$foo\&" = x"bar" \&]
+.Dq Li if \&[ x\&"$foo\&" = x"bar" \&]
instead, or the double-bracket operator
-.Dq if \&[[ $foo = bar \&]]
+.Dq Li if \&[[ $foo = bar \&]]
or, to avoid pattern matching (see
.Ic \&[[
above):
-.Dq if \&[[ $foo = \&"$bar" \&]]
+.Dq Li if \&[[ $foo = \&"$bar" \&]]
.Pp
The
-.Ic \&[[ ... ]]
+.Ic \&[[ ... \&]]
construct is not only more secure to use but also often faster.
.Pp
.It Xo
If the first operand is a decimal unsigned integer, this resets all
specified signals to the default action, i.e. is the same as calling
.Ic trap
-with a minus sign
-.Pq Sq \-
+with a dash
+.Pq Dq Li \-
as
.Ar handler ,
followed by the arguments
.Ar signal Ns s
are received.
.Ar handler
-is either an empty string, indicating the signals are to be ignored,
-a minus sign
-.Pq Sq \- ,
+is either an empty string, indicating the signals are to be ignored, a dash
+.Pq Dq Li \- ,
indicating that the default action is to be taken for the signals
.Pq see Xr signal 3 ,
or a string containing shell commands to be executed at the first opportunity
-(i.e. when the current command completes, or before printing the next
+(i.e. when the current command completes or before printing the next
.Ev PS1
prompt) after receipt of one of the signals.
.Ar signal
current attributes of all parameters are printed as
.Ic typeset
commands; if an option is given (or
-.Ql \-
+.Dq Li \-
with no option letter), all parameters and their values with the specified
attributes are printed; if options are introduced with
.Ql + ,
to fit the field width.
.It Fl l
Lower case attribute.
-All upper case characters in values are converted to lower case.
+All upper case ASCII characters in values are converted to lower case.
(In the original Korn shell, this parameter meant
.Dq long integer
when used with the
.Ar name
is accessed.
This can be used by functions to access variables whose names are
-passed as parametres, instead of using
+passed as parameters, instead of using
.Ic eval .
.It Fl p
Print complete
This option is not in the original Korn shell.
.It Fl u
Upper case attribute.
-All lower case characters in values are converted to upper case.
+All lower case ASCII characters in values are converted to upper case.
(In the original Korn shell, this parameter meant
.Dq unsigned integer
when used with the
.Fl l ,
.Fl R ,
.Fl U ,
-.Fl u ,
+.Fl u
or
.Fl Z
options are changed, all others from this set are cleared,
.Op Fl S
.Op Ar mask
.Xc
-Display or set the file permission creation mask, or umask (see
+Display or set the file permission creation mask or umask (see
.Xr umask 2 ) .
If the
.Fl S
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,
-.Dq ug=rwx,o=
-sets the mask so files will not be readable, writable, or executable by
+.Dq Li ug=rwx,o=
+sets the mask so files will not be readable, writable or executable by
.Dq others ,
and is equivalent (on most systems) to the octal mask
-.Dq 007 .
+.Dq Li 007 .
.Pp
.It Xo
.Ic unalias
is that of the last specified job; if the last job is killed by a signal, the
exit status is 128 + the number of the signal (see
.Ic kill Fl l Ar exit-status
-above); if the last specified job can't be found (because it never existed, or
+above); if the last specified job can't be found (because it never existed or
had already finished), the exit status of
.Ic wait
is 127.
below for the format of
.Ar job .
.Ic wait
-will return if a signal for which a trap has been set is received, or if a
+will return if a signal for which a trap has been set is received or if a
.Dv SIGHUP ,
-.Dv SIGINT ,
+.Dv SIGINT
or
.Dv SIGQUIT
signal is received.
job is stopped or restarted, respectively.
.Pp
Note that only commands that create processes (e.g. asynchronous commands,
-subshell commands, and non-built-in, non-function commands) can be stopped;
+subshell commands and non-built-in, non-function commands) can be stopped;
commands like
.Ic read
cannot be.
.Pp
When a job is created, it is assigned a job number.
For interactive shells, this number is printed inside
-.Dq \&[..] ,
+.Dq Li \&[...] ,
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
.Ic bg ,
.Ic fg ,
.Ic jobs ,
-.Ic kill ,
+.Ic kill
and
.Ic wait
commands either by the process ID of the last process in the command pipeline
(as stored in the
-.Ic $!\&
-parameter) or by prefixing the job number with a percent
-sign
-.Pq Sq % .
+.Ic \&$!
+parameter) or by prefixing the job number with a percent sign
+.Pq Ql % .
Other percent sequences can also be used to refer to jobs:
.Bl -tag -width "%+ x %% x %XX"
.It %+ \*(Ba %% \*(Ba %
-The most recently stopped job, or, if there are no stopped jobs, the oldest
+The most recently stopped job or, if there are no stopped jobs, the oldest
running job.
.It %\-
The job that would be the
.Ic kill Fl l
for a list of signal descriptions.
The
-.Dq core dumped
+.Dq Li core dumped
message indicates the process created a core file.
.El
.It Ar command
compliant in places where the defaults or opinions differ.
Note that
.Nm mksh
-will still operate with unsigned 32-bit arithmetics; use
+will still operate with unsigned 32-bit arithmetic; use
.Nm lksh
-if arithmetics on the host
+if arithmetic on the host
.Vt long
-data type, complete with ISO C Undefined Behaviour, are required;
+data type, complete with ISO C Undefined Behaviour, is required;
refer to the
.Xr lksh 1
manual page for details.
Most other historic,
.At
-.Nm ksh Ns -compatible ,
+.Nm ksh Ns -compatible
or opinionated differences can be disabled by using this mode; these are:
.Bl -bullet
.It
The
.Nm echo
builtin does not interpret backslashes and only supports the exact option
-.Dq Fl n .
+.Dq Li \-n .
.It
\&... (list is incomplete and may change for R54)
.El
The
.Nm echo
builtin does not interpret backslashes and only supports the exact option
-.Dq Fl n .
+.Dq Li \-n .
.It
The substitution operations
.Sm off
.Xr tty 4
in an interactive session, controlled by the
.Ic emacs ,
-.Ic gmacs ,
+.Ic gmacs
and
.Ic vi
options (at most one of these can be set at once).
parameter),
a
.Ql \*(Gt ,
-.Ql + ,
+.Ql +
or
.Ql \*(Lt
character is displayed in the last column indicating that there are more
The line is scrolled horizontally as necessary.
.Pp
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.
+IFS octet or IFS white space or are the same as the previous line.
.Ss Emacs editing mode
When the
.Ic emacs
.Xc
Moves the cursor backward to the beginning of the word; words consist of
alphanumerics, underscore
-.Pq Sq _ ,
+.Pq Ql _
and dollar sign
-.Pq Sq $
+.Pq Ql $
characters.
.It beginning\-of\-history: \*(ha[\*(Lt
Moves to the beginning of the history.
.Op Ar n
.No \*(ha[C , \*(ha[c
.Xc
-Uppercase the first character in the next
+Uppercase the first ASCII character in the next
.Ar n
words, leaving the cursor past the end of the last word.
.It clear\-screen: \*(ha[\*(haL
.Ic complete
command described above.
.It complete\-list: \*(haI, \*(ha[=
-Complete as much as is possible of the current word,
+Complete as much as is possible of the current word
and list the possible completions for it.
If only one completion is possible,
match as in the
.Op Ar n
.No \*(ha[. , \*(ha[_
.Xc
-The last word, or, if given, the
+The last word or, if given, the
.Ar n Ns th
word (zero-based) of the previous (on repeated execution, second-last,
third-last, etc.) command is inserted at the cursor.
.It set\-mark\-command: \*(ha[ Ns Aq space
Set the mark at the cursor position.
.It transpose\-chars: \*(haT
-If at the end of line, or if the
+If at the end of line or, if the
.Ic gmacs
option is set, this exchanges the two previous characters; otherwise, it
exchanges the previous and current characters and moves the cursor one
You start out in insert mode.
.It
There are file name and command completion commands:
-=, \e, *, \*(haX, \*(haE, \*(haF, and, optionally,
+=, \e, *, \*(haX, \*(haE, \*(haF and, optionally,
.Aq tab
and
.Aq esc .
(see
.Xr stty 1 )
and have their usual meaning (normal values are in parentheses): kill (\*(haU),
-erase (\*(ha?), werase (\*(haW), eof (\*(haD), intr (\*(haC), and quit (\*(ha\e).
+erase (\*(ha?), werase (\*(haW), eof (\*(haD), intr (\*(haC) and quit (\*(ha\e).
In addition to
the above, the following characters are also treated specially in insert mode:
.Bl -tag -width XJXXXXM
Erases previous character.
.It \*(haJ \*(Ba \*(haM
End of line.
-The current line is read, parsed, and executed by the shell.
+The current line is read, parsed and executed by the shell.
.It \*(haV
Literal next.
The next character typed is not treated specially (can be used
cursor.
A
.Dq 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.\&
-.Dq ab2*&\*(ha
+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.\&
+.Dq Li ab2*&\*(ha
contains two words) and a
.Dq big-word
is a sequence of non-whitespace characters.
is not specified, the last word is inserted.
.It #
Insert the comment character
-.Pq Sq #
+.Pq Ql #
at the start of the current line and return the line to the shell (equivalent
to
.Ic I#\*(haJ ) .
.Ql \&; ,
.Ql \*(Ba ,
.Ql & ,
-.Ql \&( ,
+.Ql \&(
or
-.Ql \&) ,
+.Ql \&)
and does not contain a slash
-.Pq Sq / ,
+.Pq Ql / ,
then command expansion is done; otherwise file name expansion is done.
-Command expansion will match the big-word against all aliases, functions, and
+Command expansion will match the big-word against all aliases, functions and
built-in commands as well as any executable files found by searching the
directories in the
.Ev PATH
big-words.
.It %
Find match.
-The editor looks forward for the nearest parenthesis, bracket, or
-brace and then moves the cursor to the matching parenthesis, bracket, or brace.
+The editor looks forward for the nearest parenthesis, bracket or
+brace and then moves the cursor to the matching parenthesis, bracket or brace.
.It Xo
.Oo Ar n Oc Ns f Ns Ar c
.Xc
.Oo Ar n Oc Ns \&;
.Xc
Repeats the last
-.Ic f , F , t ,
+.Ic f , F , t
or
.Ic T
command.
.Oo Ar n Oc Ns \&,
.Xc
Repeats the last
-.Ic f , F , t ,
+.Ic f , F , t
or
.Ic T
command, but moves in the opposite direction.
Miscellaneous vi commands
.Bl -tag -width Ds
.It \*(haJ and \*(haM
-The current line is read, parsed, and executed by the shell.
+The current line is read, parsed and executed by the shell.
.It \*(haL and \*(haR
Redraw the current line.
.It Xo
Undo the last edit command.
.It U
Undo all changes that have been made to the current line.
-.It PC Home, End, Del, and cursor keys
+.It PC Home, End, Del and cursor keys
They move as expected, both in insert and command mode.
.It Ar intr No and Ar quit
The interrupt and quit terminal characters cause the current line to be
.An Charles Forsyth ,
who kindly agreed to, in countries where the Public Domain status of the work
may not be valid, grant a copyright licence to the general public to deal in
-the work without restriction and permission to sublicence derivates under the
-terms of any (OSI approved) Open Source licence,
+the work without restriction and permission to sublicence derivatives under
+the terms of any (OSI approved) Open Source licence,
and parts of the BRL shell by
.An Doug A. Gwyn ,
.An Doug Kingston ,
.An Ron Natalie ,
.An Arnold Robbins ,
-.An Lou Salkind ,
+.An Lou Salkind
and others.
The first release of
.Nm pdksh
.An Eric Gisin ,
and it was subsequently maintained by
.An John R. MacMillan ,
-.An Simon J. Gerraty ,
+.An Simon J. Gerraty
and
.An Michael Rendell .
The effort of several projects, such as Debian and OpenBSD, and other
contributors including our users, to improve the shell is appreciated.
-See the documentation, CVS, and web site for details.
+See the documentation, web site and CVS for details.
.Pp
The BSD daemon is Copyright \(co Marshall Kirk McKusick.
The complete legalese is at:
has a different scope model from
.At
.Nm ksh ,
-which leads to subtile differences in semantics for identical builtins.
+which leads to subtle differences in semantics for identical builtins.
This can cause issues with a
.Ic nameref
to suddenly point to a local variable by accident; fixing this is hard.
.Ed
.Pp
.Nm mksh
-provides a consistent set of 32-bit integer arithmetics, both signed
-and unsigned, with defined wraparound and sign of the result of a
-remainder operation, even (defying POSIX) on 36-bit and 64-bit systems.
+provides a consistent 32-bit integer arithmetic implementation, both
+signed and unsigned, with sign of the result of a remainder operation
+and wraparound defined, even (defying POSIX) on 36-bit and 64-bit systems.
.Pp
.Nm mksh
provides a consistent, clear interface normally.
.Sh BUGS
Suspending (using \*(haZ) pipelines like the one below will only suspend
the currently running part of the pipeline; in this example,
-.Dq fubar
+.Dq Li fubar
is immediately printed on suspension (but not later after an
.Ic fg ) .
.Bd -literal -offset indent
.Ev HISTFILE
does not free old history entries (leaks memory) and leaks
old entries into the new history if their line numbers are
-not overwritten by same-numer entries from the persistent
+not overwritten by same-number entries from the persistent
history file; truncating the on-disc file to
.Ev HISTSIZE
lines has always been broken and prone to history file corruption
.Xr memmove 3 .
.Pp
This document attempts to describe
-.Nm mksh\ R53
+.Nm mksh\ R54
and up,
.\" with vendor patches from insert-your-name-here,
compiled without any options impacting functionality, such as