mksh FAQ

Sponsored by
HostEurope Logo

mksh FAQ

MirBSD Korn Shell — frequently asked questions

This list is an (incomplete; feedback and patches welcome) attempt to answer questions that people often have about mksh, the MirBSD Korn Shell.

You might also wish to read the homepage of the #ksh IRC channel on Freenode which lists several resources for Korn or POSIX-compatible shells in general.

Table of contents

How do you spell mksh? How do you pronounce it?

The shell is spelt either “mksh” (with an initial lowercase letter, this is important) or “MirBSD Korn Shell”.

I usually pronounce it as “em-ka-es-ha”, that is, the letters individually in my native German, or say “MirBSD Korn Shell”, although it is manageable, mostly for Slavic speakers, to actually say “mksh” as if it were a word ☺

Oh… I’ve run into this one, didn’t I? “MirBSD” is pronounced “Mir-Be-Es-De” germanically, for anglophones “Mir-beas’tie” is fine.

I’m a $OS (Android, …) user, so what’s mksh?

mksh is a so-called (Unix) “shell” or “command interpreter”, similar to COMMAND.COM, CMD.EXE or PowerShell on other operating systems you might know. Basically, it runs in a terminal (“console” or “DOS box”) window, taking user input and running that as commands. It’s also used to write so-called (shell) “script”s, short programs made by putting several of those commands into a “batch file”.

On Android, mksh is used as the system shell — basically, the one running commands at system startup, in the background, and on user behalf (but never of its own). Any privilege pop-ups you might be encountering are therefore not caused by mksh but by some other code invoking mksh to do something on its behalf.

How should I package mksh? (common cases)

Export a few environment variables, namely CC (the C compiler), CPPFLAGS (all C præprocessor definitions), CFLAGS (only compiler flags, no -Dfoo or anything!), LDFLAGS (for anything to pass to the C compiler while linking) and LIBS (appended to the linking command line after everything else. You might wish to export LDSTATIC=-static for a static build as well.

When cross-compiling, CC is the cross compiler (mksh currently does not require a compiler targetting the build system), but you must also export TARGET_OS to whatever system you are compiling for, e.g. “Linux”. For most operating systems, that’s just the uname(1) output. Some very rare systems also need TARGET_OSREV; consult the source code of Build.sh for details.

Create two subdirectories, say build-mksh and build-lksh. In each of them, start a compilation by issuing sh ../Build.sh -r followed by running the testsuite¹ via ./test.sh. For lksh(1) add -DMKSH_BINSHPOSIX to CPPFLAGS and use sh ../Build.sh -r -L to compile.

See below if the testsuite fails.

Install build-mksh/mksh as /bin/mksh (or similar), build-lksh/lksh as /bin/lksh with a symlink(7) to it from /bin/sh (if desred), and mksh.1 and lksh.1 as manpages (mdoc macropackage required). Install dot.mkshrc either as /etc/skel/.mkshrc (meaning your users will have to manually resynchronise their home directories’ copies after every package upgrade) or as /etc/mkshrc, in which case you install a redirection script like Debian’s into /etc/skel/.mkshrc. If you need a summary of the licence information, take it.

At runtime, the presence of /bin/ed as default history editor is recommended, as well as a manpage formatter; you can also install preformatted manpages from build-*ksh/*ksh.cat1 if nroff(1) (or $NROFF) is available at build time by removing the -r flag from either Build.sh invocation.

Some shell features require the ability to create temporary files and FIFOS (cf. mkfifo(2))/pipes at runtime. Set TMPDIR to a suitable location if /tmp isn’t it; if this is known ahead of time, you can add -DMKSH_DEFAULT_TMPDIR=\"/path/to/tmp\" to CPPFLAGS. We currently are unable to determine one on Android because its bionic libc does not expose any method suitable to do so in the generic case.

① To run the testsuite, ed(1) must be available as /bin/ed, and perl(1) is needed. When cross-compiling, the version of the first ed binary on the PATH must be the same as that in the target system on which the tests are to be run, in order to be able to detect which flavour of ed to adjust the tests for. Busybox ed is broken beyond repair, and all three ed-related tests will always fail with it.

The testsuite fails!

The mksh testsuite has uncovered numerous bugs in operating systems (kernels, libraries), compilers and toolchains. It is likely that you just ran into one. If you’re using LTO (the Build.sh option -c lto) try to disable it first — especially GCC is a repeat offender breaking LTO and its antecessor -fwhole-program --combine and tends to do wrong code generation quite a bit. Otherwise, try lowering the optimisation levels, bisecting, etc.

Why doesn’t this use a Makefile to build?

Not all supported target operating environments have a make utility available, and shell was required for “mirtoconf” (like autoconf) already anyway, so it was chosen to run the make part as well.

You can, however, add the -M flag to your Build.sh invocations to let it produce a Makefrag.inc file tailored for this specific build which you can then include in a Makefile, such as with the BSD make(1) “.include” command or GNU make equivalent. It even contains, for the user to start out with, a commented-out example of how to do that in the most basic manner.

Why do other BSDs and QNX still use pdksh instead of mksh?

Some systems are resistent to change, mostly due to bikeshedding (some people would, for example, rather see all shells banned to ports/pkgsrc®) and hysterial raisins (historical reasons ☻). Most BSDs have mksh packages available, and it works on all of them and QNX just fine.

In fact, on all of these systems, you can replace their 1999-era /bin/ksh (which is a pdksh) with mksh. On at least NetBSD® 1.6 and up (not 1.5) and OpenBSD, even /bin/sh is fair game.

MidnightBSD notably has adopted mksh as system shell (thanks laffer1).

Why is there no mksh in OpenBSD’s ports tree?

OpenBSD don’t like people who fork off their project at all; heck, they don’t even like the people they themselves forked off (NetBSD®). Several people tried over the years to get one committed, but nobody dared so as to not lose their commit bit. If you try, succeed, and survive Theo, however, kudos to you! See also the “other BSDs” FAQ entry.

I’m an OS/2 user, what do I need to know?

This issue is discussed at more length in the FAQ section in the manpage. You can install plain mksh (usually by compiling it yourself) which behaves like one expects from a Unix shell in a Unix environment (LF line endings, binary mode file I/O, etc.) or “mksh-os2” from komh (binaries on Hobbes), which are built from the same source with the -T flag, enabling “textmode” to behave more similar to native applications (CR+LF line endings, text mode file I/O, etc).

I’d like an introduction.

Unfortunately, nobody has written a book about mksh yet, although other shells have received (sometimes decent) attention from authors and publishers. This FAQ lists a subset of things packagers and generic people ask, and the mksh(1) manpage is more of a reference, so you are probably best off starting with a shell-agnostic, POSIX or ksh88 reference such as the first edition (the second one deals with ksh93 which differs far more from mksh than ksh88, as ancient as it is, does) of the O’Reilly book (⚠ disclaimer: only an example, not a recommendation) and going forward by reading scripts (the “shellsnippets” repository referenced in the #ksh channel homepage (see the top of this document) has many examples) and trying to understand them and the mksh specifics from the manpage.

My prompt from <some other shell> does not work!

Contact us on the mailing list or on IRC, we'll convert it for you. Also have a look at the PS1 section in the mksh(1) manpage (search for “otherwise unused char”, e.g. with / in less(1), to spot it quickly).

My question is not answered here!

Check out the FAQ section at the end of the mksh(1) manual page which contains questions that are in user scope; this webpage collects those about mksh in general, by packagers, etc.

How do I contact you (to say thanks)?

You can say hi in the #!/bin/mksh channel on Freenode IRC, although a donation wouldn’t be amiss ☺ The mailing list can also be used.

MirOS Logo