introduce a FAQ, move lots of stuff there and add lots of stuff
This commit is contained in:
parent
1dd5ae69ae
commit
0935faa52b
249
mksh.1
249
mksh.1
@ -1,4 +1,4 @@
|
|||||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.433 2017/03/19 20:59:27 tg Exp $
|
.\" $MirOS: src/bin/mksh/mksh.1,v 1.434 2017/03/19 22:04:49 tg Exp $
|
||||||
.\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $
|
.\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $
|
||||||
.\"-
|
.\"-
|
||||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||||
@ -186,30 +186,8 @@ sometimes does take portable shell scripting or various standards
|
|||||||
into account all information is first and foremost presented with
|
into account all information is first and foremost presented with
|
||||||
.Nm
|
.Nm
|
||||||
in mind and should be taken as such.
|
in mind and should be taken as such.
|
||||||
.Ss I'm an Android user, so what's mksh?
|
.Ss I use Android, OS/2, etc. so what...?
|
||||||
.Nm mksh
|
Please see the FAQ at the end of this document.
|
||||||
is a
|
|
||||||
.Ux
|
|
||||||
shell / command interpreter, similar to
|
|
||||||
.Nm COMMAND.COM
|
|
||||||
or
|
|
||||||
.Nm CMD.EXE ,
|
|
||||||
which has been included with
|
|
||||||
.Tn 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
|
|
||||||
.Nm mksh
|
|
||||||
issues but questions by some other program utilising it.
|
|
||||||
.Ss "I'm an OS/2 user, what do I need to know?"
|
|
||||||
Unlike the native command prompt, the current working directory is
|
|
||||||
not in the search path at all, for security reasons common on Unix
|
|
||||||
systems (the shell is designed for Unix-like systems); if you really
|
|
||||||
need this, run the command
|
|
||||||
.Li PATH=".;$PATH"
|
|
||||||
or add that to a suitable initialisation file.
|
|
||||||
.Ss Invocation
|
.Ss Invocation
|
||||||
Most builtins can be called directly, for example if a link points from its
|
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.
|
name to the shell; not all make sense, have been tested or work at all though.
|
||||||
@ -2134,7 +2112,7 @@ Due to a strong suggestion from David G. Korn,
|
|||||||
.Nm
|
.Nm
|
||||||
now also supports the following form:
|
now also supports the following form:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
PS1=$'\e1\er\e1\ee[7m\e1$PWD\e1\ee[0m\e1\*(Gt '
|
PS1=$\*(aq\e1\er\e1\ee[7m\e1$PWD\e1\ee[0m\e1\*(Gt \*(aq
|
||||||
.Ed
|
.Ed
|
||||||
.It Ev PS2
|
.It Ev PS2
|
||||||
Secondary prompt string, by default
|
Secondary prompt string, by default
|
||||||
@ -2587,7 +2565,7 @@ Redirections are processed after
|
|||||||
pipelines are created and in the order they are given, so the following
|
pipelines are created and in the order they are given, so the following
|
||||||
will print an error with a line number prepended to it:
|
will print an error with a line number prepended to it:
|
||||||
.Pp
|
.Pp
|
||||||
.D1 $ cat /foo/bar 2\*(Gt&1 \*(Gt/dev/null \*(Ba pr \-n \-t
|
.Dl $ cat /foo/bar 2\*(Gt&1 \*(Gt/dev/null \*(Ba pr \-n \-t
|
||||||
.Pp
|
.Pp
|
||||||
File descriptors created by I/O redirections are private to the shell.
|
File descriptors created by I/O redirections are private to the shell.
|
||||||
.Ss Arithmetic expressions
|
.Ss Arithmetic expressions
|
||||||
@ -3743,7 +3721,7 @@ the parsing or evaluation of an expression, the exit status is greater than 1.
|
|||||||
Since expressions may need to be quoted,
|
Since expressions may need to be quoted,
|
||||||
.No \&(( Ar expr No ))
|
.No \&(( Ar expr No ))
|
||||||
is syntactic sugar for:
|
is syntactic sugar for:
|
||||||
.Dl "{ \e\ebuiltin let '" Ns Ar expr Ns "'; }"
|
.Dl "{ \e\ebuiltin let \*(aq" Ns Ar expr Ns "\*(aq; }"
|
||||||
.Pp
|
.Pp
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic mknod
|
.Ic mknod
|
||||||
@ -3981,40 +3959,6 @@ If no input is read or a timeout occurred,
|
|||||||
.Ic read
|
.Ic read
|
||||||
exits with a non-zero status.
|
exits with a non-zero status.
|
||||||
.Pp
|
.Pp
|
||||||
Another handy set of tricks:
|
|
||||||
If
|
|
||||||
.Ic read
|
|
||||||
is run in a loop such as
|
|
||||||
.Ic while read foo; do ...; done
|
|
||||||
then leading whitespace will be removed (IFS) and backslashes processed.
|
|
||||||
You might want to use
|
|
||||||
.Ic while IFS= read \-r foo; do ...; done
|
|
||||||
for pristine I/O.
|
|
||||||
Similarly, when using the
|
|
||||||
.Fl a
|
|
||||||
option, use of the
|
|
||||||
.Fl r
|
|
||||||
option might be prudent; the same applies for:
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
find . \-type f \-print0 \*(Ba& \e
|
|
||||||
while IFS= read \-d \*(aq\*(aq \-pr filename; do
|
|
||||||
print \-r \-\- "found \*(Lt${filename#./}\*(Gt"
|
|
||||||
done
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
The inner loop will be executed in a subshell and variable changes
|
|
||||||
cannot be propagated if executed in a pipeline:
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
bar \*(Ba baz \*(Ba while read foo; do ...; done
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
Use co-processes instead:
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
bar \*(Ba baz \*(Ba&
|
|
||||||
while read \-p foo; do ...; done
|
|
||||||
exec 3\*(Gt&p; exec 3\*(Gt&\-
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic readonly
|
.Ic readonly
|
||||||
.Op Fl p
|
.Op Fl p
|
||||||
@ -5742,9 +5686,6 @@ Goes to history number
|
|||||||
.No KILL Pq \*(haU
|
.No KILL Pq \*(haU
|
||||||
.Xc
|
.Xc
|
||||||
Deletes the entire input line.
|
Deletes the entire input line.
|
||||||
If Ctrl-U should only delete the line up to the cursor, use:
|
|
||||||
.Pp
|
|
||||||
.D1 $ bind \-m \*(haU='\*(ha[0\*(haK'
|
|
||||||
.It kill\-region: \*(haW
|
.It kill\-region: \*(haW
|
||||||
Deletes the input between the cursor and the mark.
|
Deletes the input between the cursor and the mark.
|
||||||
.It Xo kill\-to\-eol:
|
.It Xo kill\-to\-eol:
|
||||||
@ -6623,24 +6564,6 @@ The complete legalese is at:
|
|||||||
.\" to protect it or lose it, which McKusick almost did.
|
.\" to protect it or lose it, which McKusick almost did.
|
||||||
.\"
|
.\"
|
||||||
.Sh CAVEATS
|
.Sh CAVEATS
|
||||||
.Nm
|
|
||||||
has a different scope model from
|
|
||||||
.At
|
|
||||||
.Nm ksh ,
|
|
||||||
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.
|
|
||||||
.Pp
|
|
||||||
The parts of a pipeline, like below, are executed in subshells.
|
|
||||||
Thus, variable assignments inside them are not visible in the
|
|
||||||
surrounding execution environment.
|
|
||||||
Use co-processes instead.
|
|
||||||
.Bd -literal -offset indent
|
|
||||||
foo \*(Ba bar \*(Ba read baz # will not change $baz
|
|
||||||
foo \*(Ba bar \*(Ba& read \-p baz # will, however, do so
|
|
||||||
.Ed
|
|
||||||
.Pp
|
|
||||||
.Nm mksh
|
.Nm mksh
|
||||||
provides a consistent 32-bit integer arithmetic implementation, both
|
provides a consistent 32-bit integer arithmetic implementation, both
|
||||||
signed and unsigned, with sign of the result of a remainder operation
|
signed and unsigned, with sign of the result of a remainder operation
|
||||||
@ -6685,6 +6608,8 @@ case ${KSH_VERSION:\-} in
|
|||||||
esac
|
esac
|
||||||
.Ed
|
.Ed
|
||||||
In near future, (Unicode) locale tracking will be implemented though.
|
In near future, (Unicode) locale tracking will be implemented though.
|
||||||
|
.Pp
|
||||||
|
See also the FAQ below.
|
||||||
.Sh BUGS
|
.Sh BUGS
|
||||||
Suspending (using \*(haZ) pipelines like the one below will only suspend
|
Suspending (using \*(haZ) pipelines like the one below will only suspend
|
||||||
the currently running part of the pipeline; in this example,
|
the currently running part of the pipeline; in this example,
|
||||||
@ -6735,3 +6660,161 @@ IRC channel at
|
|||||||
.Pq Port 6697 SSL, 6667 unencrypted ,
|
.Pq Port 6697 SSL, 6667 unencrypted ,
|
||||||
or at:
|
or at:
|
||||||
.Pa https://launchpad.net/mksh
|
.Pa https://launchpad.net/mksh
|
||||||
|
.Sh FREQUENTLY ASKED QUESTIONS
|
||||||
|
This FAQ attempts to document some of the questions users of
|
||||||
|
.Nm
|
||||||
|
or readers of this manual page may encounter.
|
||||||
|
.Ss I'm an Android user, so what's mksh?
|
||||||
|
.Nm mksh
|
||||||
|
is a
|
||||||
|
.Ux
|
||||||
|
shell / command interpreter, similar to
|
||||||
|
.Nm COMMAND.COM
|
||||||
|
or
|
||||||
|
.Nm CMD.EXE ,
|
||||||
|
which has been included with
|
||||||
|
.Tn 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
|
||||||
|
.Nm mksh
|
||||||
|
issues but questions by some other program utilising it.
|
||||||
|
.Ss "I'm an OS/2 user, what do I need to know?"
|
||||||
|
Unlike the native command prompt, the current working directory is
|
||||||
|
not in the search path at all, for security reasons common on Unix
|
||||||
|
systems (the shell is designed for Unix-like systems); if you really
|
||||||
|
need this, run the command
|
||||||
|
.Li PATH=".;$PATH"
|
||||||
|
or add that to a suitable initialisation file.
|
||||||
|
.Pp
|
||||||
|
You will have gotten this shell through komh's port on Shellworld
|
||||||
|
most likely. It differs from standard mksh in that ASCII (CR+LF)
|
||||||
|
newlines are accepted in many places.
|
||||||
|
.Ss "How do I start mksh on a specific terminal?"
|
||||||
|
Normally:
|
||||||
|
.Dl mksh \-T/dev/tty2
|
||||||
|
.Pp
|
||||||
|
However, if you want for it to return (e.g. for an embedded
|
||||||
|
system rescue shell), use this on your real console device instead:
|
||||||
|
.Dl mksh \-T!/dev/ttyACM0
|
||||||
|
.Pp
|
||||||
|
.Nm
|
||||||
|
can also daemonise (send to the background):
|
||||||
|
.Dl mksh \-T\- \-c \*(aqexec cdio lock\*(aq
|
||||||
|
.Ss "POSIX says..."
|
||||||
|
Run the shell in POSIX mode (and possibly
|
||||||
|
.Nm lksh
|
||||||
|
instead of
|
||||||
|
.Nm mksh ) :
|
||||||
|
.Dl set \-o posix
|
||||||
|
.Ss "My prompt from <some other shell> does not work!"
|
||||||
|
Contact us on the mailing list or on IRC, we'll convert it for you.
|
||||||
|
.Ss "Something is going wrong with my while...read loop"
|
||||||
|
Most likely, you've encountered the problem in which the shell runs
|
||||||
|
all parts of a pipeline as subshell.
|
||||||
|
The inner loop will be executed in a subshell and variable changes
|
||||||
|
cannot be propagated if run in a pipeline:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
bar \*(Ba baz \*(Ba while read foo; do ...; done
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Use co-processes instead:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
bar \*(Ba baz \*(Ba&
|
||||||
|
while read \-p foo; do ...; done
|
||||||
|
exec 3\*(Gt&p; exec 3\*(Gt&\-
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
If
|
||||||
|
.Ic read
|
||||||
|
is run in a loop such as
|
||||||
|
.Ic while read foo; do ...; done
|
||||||
|
then leading whitespace will be removed (IFS) and backslashes processed.
|
||||||
|
You might want to use
|
||||||
|
.Ic while IFS= read \-r foo; do ...; done
|
||||||
|
for pristine I/O.
|
||||||
|
Similarly, when using the
|
||||||
|
.Fl a
|
||||||
|
option, use of the
|
||||||
|
.Fl r
|
||||||
|
option might be prudent
|
||||||
|
.Pq Dq Li read \-raN\-1 arr \*(Ltfile ;
|
||||||
|
the same applies for NUL-terminated lines:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
find . \-type f \-print0 \*(Ba& \e
|
||||||
|
while IFS= read \-d \*(aq\*(aq \-pr filename; do
|
||||||
|
print \-r \-\- "found \*(Lt${filename#./}\*(Gt"
|
||||||
|
done
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
.Ss "What differences in function-local scopes are there?"
|
||||||
|
.Nm
|
||||||
|
has a different scope model from
|
||||||
|
.At
|
||||||
|
.Nm ksh ,
|
||||||
|
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.
|
||||||
|
.Pp
|
||||||
|
.Tn GNU
|
||||||
|
.Nm bash
|
||||||
|
allows unsetting local variables; in
|
||||||
|
.Nm ,
|
||||||
|
doing so in a function allows back access to the global variable
|
||||||
|
(actually the one in the next scope up) with the same name.
|
||||||
|
The following code, when run before the function definitions, changes
|
||||||
|
the behaviour of
|
||||||
|
.Ic unset
|
||||||
|
to behave like other shells (the alias can be removed after the definitions):
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
case ${KSH_VERSION:\-} in
|
||||||
|
*MIRBSD\ KSH*\*(Ba*LEGACY\ KSH*)
|
||||||
|
function unset_compat {
|
||||||
|
\e\ebuiltin typeset unset_compat_x
|
||||||
|
|
||||||
|
for unset_compat_x in "$@"; do
|
||||||
|
eval "\e\e\e\ebuiltin unset $unset_compat_x[*]"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
\e\ebuiltin alias unset=unset_compat
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
When a local variable is created (e.g. using
|
||||||
|
.Ic local ,
|
||||||
|
.Ic typeset ,
|
||||||
|
.Ic integer ,
|
||||||
|
.Ic \e\ebuiltin typeset )
|
||||||
|
it does not, like in other shells, inherit the value from the global
|
||||||
|
(next scope up) variable with the same name; it is rather created
|
||||||
|
without any value (unset but defined).
|
||||||
|
.Ss "I get an error in this regex comparison"
|
||||||
|
Use extglobs instead of regexes:
|
||||||
|
.Dl "[[ foo =~ (foo\*(Babar).*baz ]] # becomes"
|
||||||
|
.Dl "[[ foo = *@(foo\*(Babar)*baz* ]] # instead"
|
||||||
|
.Ss "Are there any extensions to avoid?"
|
||||||
|
.Tn GNU
|
||||||
|
.Nm bash
|
||||||
|
supports
|
||||||
|
.Dq Li &\*(Gt
|
||||||
|
.Pq and Dq Li \*(Ba&
|
||||||
|
to redirect both stdout and stderr in one go, but this breaks POSIX
|
||||||
|
and Korn Shell syntax; use POSIX redirections instead:
|
||||||
|
.Dl "foo \*(Ba& bar \*(Ba& baz &\*(Gtlog # GNU bash"
|
||||||
|
.Dl "foo 2\*(Gt&1 \*(Ba bar 2\*(Gt&1 \*(Ba baz \*(Gtlog 2\*(Gt&1 # POSIX"
|
||||||
|
.Ss "\*(haL (Ctrl-L) does not clear the screen"
|
||||||
|
Use \*(ha[\*(haL (Escape+Ctrl-L) or rebind it:
|
||||||
|
.Dl bind \*(aq\*(haL=clear-screen\*(aq
|
||||||
|
.Ss "\*(haU (Ctrl-U) clears the entire line"
|
||||||
|
If it should only delete the line up to the cursor, use:
|
||||||
|
.Dl bind \-m \*(haU=\*(aq\*(ha[0\*(haK\*(aq
|
||||||
|
.Ss "Cursor Up behaves differently from zsh"
|
||||||
|
Some shells make Cursor Up search in the history only for
|
||||||
|
commands starting with what was already entered.
|
||||||
|
.Nm
|
||||||
|
separates the shortcuts: Cursor Up goes up one command
|
||||||
|
and PgUp searches the history as described above.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user