The MirBSD Korn Shell

FOSS hosting by
HostEurope Logo

The MirBSD Korn Shell

(Some information on this page — mostly plans and older docs — are possibly outdated, wrong or historic, although we moved most of them off to other subpages.)

Table of Contents

mksh(1) R59c

This is the website of the MirBSD™ Korn Shell, an actively developed free implementation of the Korn Shell programming language and a successor to the Public Domain Korn Shell (pdksh).

mksh Logo This page is always accessible via a redirection at, which is the canonical homepage URI. There also is (most of the time) mksh on Freshmeat and an mksh project page on ohlol, a statistics site. mksh is experimentally tracked at Launchpad. Download the Logo as SVG if you want. There’s also a full licence terms overview; it suffices to say mksh is Ⓕ Copyfree licenced.

mksh must always be written either “mksh” (all-lowercase) or “MirBSD Korn Shell” — there is no other spelling. It’s usually pronounced by spelling out the four letters m, k, s and h individually, or by saying “MirBSD Korn Shell”.


The current version of mksh is mksh R59c from 31 October 2020.

Thanks to “Der Verein” for providing access to a Solaris 8 box. Thanks to Julian “yofuh” Wiesener for just another account on a Sun E420 on Solaris 11β. Thanks to someone who prefers to stay anonymous due to tons of red tape for providing access to an AIX 5.3 system with gcc and xlC installed. (Both are now defunct.) Thanks to Jupp “cnuke” Söntgen for building on AIX in Dresden nowadays. Thanks to HP TestDrive/PvP/DSPP/CLOE, which helps in keeping mksh portable to several Unixes and compilers, and track down some architecture- or glibc-specific bugs. (These days, HP-UX/IA64 only, though.) Thanks to gnubber’s admin (Barry “bddebian” deFreese), as well as Samuel “youpi” Thibault, for providing shell access to a Debian GNU/Hurd system. Thanks to Lucas “laffer1” Holt for ssh access to the MidnightBSD server. Thanks to Waldemar “wbx” Brodkorb for dropping his unused Zaurus SL-C3200 to someone who can actually make use of it to test mksh on OpenBSD. Thanks to Andreas “gecko2” Gockel for access to a couple of Debian and Macintosh boxen and an iPhone 3G. Thanks to Martin Zobel-Helas for an account on an Alpha system. Thanks to Bastian “waldi” Blank for access to an S/390 system and uploading mksh packages to Debian for quite some time. Also thanks to Otavio Salvador and Patrick “aptituz” Schönfeld for uploading a couple of my Debian packages. The Debian GNU/k*BSD and Hurd developers were quite helpful in assisting and testing as well. Thanks to Thomas E. “TGEN” Spanjaard for access to both a NetBSD and a DragonFly system. Thanks to Josef “jupp” / “penpen” Schugt for testing mksh on a Digital Unix (OSF/1 V4.0) system from the Uni Bonn Physik CIP Pool. Thanks to DEChengst from #UnixNL for providing access to a HP/Compaq Tru64 (OSF/1 V5.1B) system, an OSF/1 V2.0 system and an Ultrix 4.5 system. Thanks to Adam “replaced” Hoka for a BSDi BSD/OS 3.1 ISO9660 image and offering to help with HP-sUX testing (now that HP TestDrive went down) and initial porting to Haiku, which was continued at CLT 2010 with help from Stephan Aßmus. Thanks to André “naaina” Wösten for ssh on a QNX box. Thanks to Olivier Duchateau for testing on Slackware and Zenwalk GNU/Linux. Thanks to Winston W. for spotting musl, and thanks to maximilian attems and H. Peter Anvin for almost fixing klibc. Thanks to RT|Chatzilla, Chris “ir0nh34d” Sutcliffe, and others for Win32 platform assistance. Thanks to KO Myung-Hun for the OS/2 port. Thanks to Daniel Richard G. <skunk@iSKUNK.ORG> for the z/OS (OS/390) initial porting effort and continued testing. Thanks to all other contributors from IRC and the mailing list, including, but not limited to, those already named and Martijn Dekker, Jean Delvare, izabera, J�rg Schilling, carstenh, jilles from FreeBSD, arekm, Torsten Sillke, slagtc, Stéphane Chazelas, colona, zacts, Seb, Steffen Nurpmeso (sdaoden), Dan Douglas (ormaaj), Dr. Werner Fink, … (in no particular order). Thanks to Brian Callahan from the Rensselaer Polytechnic Institute for bug fixes as well as running test builds on AIX 5.1L with the xlC and gcc-2.9, and on Solaris 8 with Forte Developer 7 C 5.4 and gcc 2.95.2 and 3.4.6 compilers. Thanks Stanley J. Johnson and the MirBSD southern hemisphere manager Finn Thain, who made the A/UX port possible. Thanks to Redfoxmoon for testing on several old systems, such as HP-UX 9 (m68k), and sometimes even getting me access. No thanks to Intel for not including mksh in their programme analysing code. (Did I miss anyone? Mail me if so. Some of these are past, anyway.)

What is mksh(1)? — Short answer: The MirBSD Korn Shell. Okay, but what exactly does it do, or why another shell? These questions will be answered here for the people interested. Right now, you only need to know that mksh is a DFSG-free and OSD-compliant (and OSI approved) successor to pdksh, developed as part of the MirOS Project as native Bourne/POSIX/Korn shell for MirOS BSD, but also to be readily available under other UNIX®-like operating systems.

The source code for mksh is available at the MirOS Project mirrors as well as these of other operating system projects due to being included in these; however, we do not provide binaries. Find instructions to build and install mksh below, or ask your operating environment vendor to package and include mksh; we provide assistance for this task if asked. Licencing permits this as long as due credit is given to the authors and contributors and the copyright notices are not removed in their entirety; modifying is allowed (but if the result is still called mksh, it’s discouraged; talk with us if you feel you have to modify mksh). The individual licences used are the Ⓕ MirOS licence, and (for BSD compatibility on other operating systems) the 3-clause UCB licence and the ISC licence; full terms are available. pdksh originally was public domain, with a few exceptions, but these files are not part of mksh R21 or up. The mksh(1) author (mirabilos) acknowledges the contributions of these people who dedicated pdksh and oksh to the public, and asserts a collective copyright on the code. All these licences are DFSG clean and conform to the OSD, and the MirOS Licence is listed on the pages of the ifrOSS licence centre as well as in the FSF/UNESCO Directory of Free Software. The MirBSD Korn Shell is OSI Certified Open Source Software™ and its manual is Open Knowledge.

To compile mksh, you will need a Bourne or POSIX shell (Solaris /bin/sh is enough, the Z shell works), a C compiler, system and C library header files and the standard C runtime. You will also need a set of standard UNIX® tools on a supported operating system: any recent BSD; Darwin, Apple Mac OSX; Interix (Microsoft® Services for Unix 3.5, maybe Subsystem for Unix Applications on Win2003/Vista); GNU/Cygwin; UWIN; GNU/Linux (libc5, glibc, dietlibc, µClibc, some klibc systems are tested), Debian GNU/kFreeBSD, GNU/Hurd or GNU/Linux; Sun Solaris (8, 9, 10, 11), OpenSolaris; AIX; IRIX; HP-UX 11i; OSF/1; ULTRIX; Minix 3; NeXTstep (but not OpenStep 4.2); QNX; BeOS (with limitations) or Haiku; Xenix, SCO OpenServer 3.2r4.2 or 5 (with limitations) or 6 or SCO UnixWare; Minoca OS; …
To run the regression test suite, you will need a not too antiquated Perl optimally with or as well as /bin/ed (whose installation is strongly suggested anyway, because it’s the standard FCEDIT history editor and standard UNIX® text editor), as well as a controlling terminal, usually /dev/tty or provided from script(1) or GNU screen.

To use mksh, you only need the C runtime (and any supplemental libraries the binary was linked against) and, optionally, /bin/ed — for interactive use, a controlling terminal is highly recommended because job control does not work without one.

To make full use of mksh(1)’s interactive features, it is recommended to copy the dot.mkshrc file from the source distribution as ~/.mkshrc into the user’s home directory and let the user adjust it to suit his needs. The sample file configures a few aliases and shell functions as well as a sensible prompt ($PS1) and some csh-like directory stack functions and zsh-like hooks. Full use of this file requires a few special UNIX® tools. Note that $ENV must not be set for mksh(1) to parse the ~/.mkshrc file at startup.


We provide an online manual page in HTML and PDF format. Reading books about Korn Shells in general is recommended as further help, but beware of the differences (ATTENTION outdated content behind that link) to other shells. Some ISBNs are listed at the end of the manual page.

A collection of some frequently asked questions is available as the mksh FAQ.

If you require additional assistance or want to discuss bugs, features or enhancements, write to the miros-mksh mailing list (or subscribe to it by sending an eMail to the postmaster telling which address to subscribe to which list(s) — in your case, the miros-mksh list, but we have more mailing lists). The mailing list can be reached via the GMane archive using either NNTP or HTTP, or at The Mail Archive, although not at MARC. Joining the IRC channel #!/bin/mksh (no joke, this is really the channel’s name) is recommended as well.


Skip to the section about being included in operating environments unless you really want to compile mksh from source yourself or create a package for your operating system of choice.

First off, you have to download the source code from any of the mirrors listed below, or any other mirror you know of. Alternatively, use the development version from CVS. Official source code distributions are digitally signed with gzsig(1) using the MirOS Project’s current signature key. Please verify the signature as well as the hashes and/or checksums below, so you’re sure the content is intact and the version number on the archive is correct.

Known Mirrors

Checksums and Hashes

Preformatted Documentation


We’re using gzip(1)-compressed POSIX ustar(1) distfiles nowadays, so a simple tar -xzf mksh-R59c.tgz will work. It will create all files in a subdirectory ./mksh/.


If you’re a packager/vendor and need to patch mksh and deviate from the default behaviour for that version which is indicated from $KSH_VERSION, define the cpp(GNU) KSH_VERSIONNAME_VENDOR_EXT macro to a C string beginning with a space and a plus sign, followed by a tag of yours, e.g. add -DKSH_VERSIONNAME_VENDOR_EXT=\"\ +aCoolDistro\" to CPPFLAGS so they can be distinguished. I think this is a reasonable request.

In contrast to the old patching mode, this does not require patching the testsuite any more.


In the currently recommended mode of installation, the source code is compiled twice, once for mksh and once for lksh, in different build directories. It’s possible, even customary, to build them with diverging options — e.g. it’s strongly recommended to build lksh with -DMKSH_BINSHPOSIX so it auto-enables set -o posix when called as /bin/sh; linking it statically is also very common, although less wise when using glibc; some add -DMKSH_BINSHREDUCED and/or the printf(1) builtin as well.

Building mksh

Consider reading operating environment-specific notes first. RUN THE TESTSUITE after building (or, when cross-building, on the target system); several “alternative libcs” and other environments have known bugs that cannot be detected at configure or compile time (otherwise, we’d do that already).

Now you’re in the source code directory; does all the magic for you. In theory, invoking the command
% /bin/sh ./
should work. Relative paths can be used too, for example, instead of cd(1)ing to the source directory, you could’ve done
% mkdir build; cd build; /bin/sh ../mksh/
Doing such an “out-of-tree” build is recommended.

It is optionally possible to place files, such as printf.c, into either the current or the source directory. It will need a compile option (see building) to be activated.

The build script requires a Bourne shell (Solaris /bin/sh, the Heirloom sh, DEC OSF/1 V2.0 /bin/sh), Korn shell (ksh, ksh88, ksh93, pdksh, mksh, oksh, maybe the MKS ksh), POSIX shell (posh, /usr/xpg4/bin/sh, ash, dash, yash), a related shell (J�rg/Jvrg/Joerg/Jörg Schilling’s bosh or sh, or the Z Shell), or a Bourne or POSIX superset (such as GNU bash) to work; the ULTRIX /bin/sh or the C shell (csh, tcsh) or “bsh” or a scripting shell like the wish won’t.
Accepted arguments are:

Note: “-M” is incompatible with “-c somemode” and “-j” — specify LTO and parallel make using your make(1) tool’s facilities instead. Also, “-c dragonegg” does not work with “-j” (the former is ignored).

Note: any kind of “-c somemode” optimisation is brittle: LLVM (both llvm and dragonegg) have not been used for a long time; GCC’s LTO breaks so often we forcibly disable it nowadays and stopped offering it. Run the testsuite if you use one!

The build script also honours some environment variables detailed at its end.

Install this binary as /bin/mksh and its manual page; you may want to also install dot.mkshrc, either directly into the skeleton directory, or with a wrapper /etc/skel/.mkshrc file that reads /etc/mkshrc, especially if packaging for a GNU distribution.

Building lksh

Add the -L flag to the to create lksh(1), a variant of the shell that uses POSIX-compliant arithmetics with the host “long” data type, instead of mksh’s guaranteed-reliable 32-bit arithmetics. You probably want to add -DMKSH_BINSHPOSIX and, possibly, -DMKSH_BINSHREDUCED to the command line and install the lksh binary as your system /bin/sh if you go that route. (This shell is not intended to be used interactively. Its purpose is to run legacy sh scripts (especially with the MKSH_BINSHREDUCED option) and POSIX sh scripts, including Debian maintainer scripts.)

Install this binary as /bin/lksh and its companion manpage, but remember that it does not come stand-alone and to always ship the full proper mksh shell alongside it.

Operating Environment-specific notes

… are now on their own page.

After compiling

The script generates an executable (“mksh”, except on GNU/Cygwin, where it is called “mksh.exe”), a shell script to use the newly built mksh to run the regression test suite (“”), and (unless the -r option was given) a pre-formatted manual page (“mksh.cat1”). It also lists installation instructions unless -Q was provided. Now it’s the time to run
% ./ -v -f
in order to see if the shell works. The regression testsuite will exit with errorlevel 1 if any tests failed that are not marked as allowed to fail (e.g. OS dependent) or expected to fail, 0 otherwise. Use instead a ‘+f’ option if you do not have a fast (say 1½ GHz Pentium-M) machine.

The regression tests need a controlling tty. Please ensure you have one, even for bulk/dæmonised builds; you can use GNU screen or script(1) to provide one by running the testsuite inside it (see the Debian and OpenSuSE Buildservive packaging for examples of how to do it). If, however, you absolutely cannot get the necessary utilities and devices installed in the build chroot, run: ./ -v -C regress:no-ctty

To actually install mksh, copy the binary to some place in $PATH, i.e. /bin/mksh, $HOME/.bin/mksh, /usr/local/bin/mksh, or whatever your packaging system wants; strip it and run chmod 555 on it. (This can easily be achieved with install(1) — on Solaris, this is /usr/ucb/install not /usr/bin/install – with the arguments -c, -s, -m 755¹, and -o/-g. ① with 555, strip(1) cannot write the file any more, chmod 555 afterwards.) Also append its installation path to /etc/shells, install the dot.mkshrc file (usually alongside with the copyright file and other documentation), copy it to /etc/skel/.mkshrc if your operating environment has this means to include default dotfiles; install either the catman page (mksh.cat1) to, for example, /usr/share/man/cat1/mksh.0, or the mdoc page (mksh.1) to the standard location (/usr/share/man/man1/ or /usr/man/man1/ or whatever your operating environment requires). The manual page requires the Berkeley mdoc macros (either the BSD or the GNU groff version) to be installed during formatting time.

Note that a ~/.mkshrc file will not be executed if $ENV is set and not empty, nor is there an /etc/mkshrc.

For packagers: Upgrades

Note: This is not the ChangeLog, these are the packager-visible upgrade notes regarding changes in the build system ( and friends, compiler support, packaging conventions, bad examples, etc). This is also not the users' upgrade caveat list.
Packagers also please note: it’s mksh or “The MirBSD Korn Shell” (“MidnightBSD Korn Shell” is also appropriate), but never Mksh or somesuch!

current: Please remember to subscribe to the mksh mailing list, either directly or via GMane, if you have an interest in mksh, such as packaging it. Thanks!
Building lksh, with -DMKSH_BINSHPOSIX, and installing it alongside mksh, is now recommended more strongly, as only lksh -o posix is close to POSIX compliant. The cat and sleep builtins are gone, so linking either as multi-call binary will now fail; a portable MirBSD sleep is available to plug the hole if your system utility lacks sub-second sleep support. Please update all cached references to our IRC channels, the network we had been using was obliterated. printf.c updated. The testsuite’s default UTF-8 locale is now C.UTF-8 (except on HP/UX where we know better) so use -U if you don’t have that. When passing -DMKSH_ASSUME_UTF8={0|1} in CPPFLAGS now also set HAVE_SETLOCALE_CTYPE=0 in the environment as the former used to imply the latter but is now going to go away with locale tracking. GNU’s sigabbrev_np(3), sigdescr_np(3) and strerrordesc_np(3) are now preferred over _sys_signame[], _sys_siglist[] and _sys_errlist[]/sys_nerr respectively if present. Read musl-specific notes if building for musl! RUN THE TESTSUITE! mksh is now tested upstream with ASan/UBSan but this needs the -g option which enables debug mode whose resulting binaries, due to arbitrarily limiting e.g. recursion depth (to help fuzzers), shall not be distributed to end users. It is no longer necessary to run ./ with -f, it is now the default; on slow systems (way below 1 GHz or so) add +f instead. (unfinished…)

R59c: Please remember to build and install the HTML FAQ. Ignore deprecation warnings regarding sys_errlist and sys_nerr as alternatives will be used automatically once these are not available any more (glibc users). When using GNU coreutils consider patching dot.mkshrc to drop the -o option from lo.

R59b: Correction: Normally, that link goes from rksh, or just ship both.

R59: You can install a link from rmksh to mksh (same for lksh or sh). If necessary, an R58b with the fixes but not the breaking changes can be spun; contact me if needed.

R58: in-tree build of FAQ is broken, sorry — build out-of-tree or with this hotfix instead (cause was removed mksh.faq…). GCC’s LTO support was, as announced, removed. Do not build with LTO if you have GCC as compiler, it has wrong-code generation bugs! We try to add -fno-lto to CFLAGS if GCC is detected, since some GNU distributions forcefully enabled LTO by default despite the bugs and upstream not caring about them. The FAQ is now shipped as XHTML snippets with the source code; run to build a valid local HTML page, consider installing it

R57: The MKSH_EARLY_LOCALE_TRACKING code was fixed. The testsuite now checks whether there is actually a controlling tty available or not and whether it matches what’s passed for options. The vendor patching info was updated.

R56c: SuSE provided a patch to implement mediæval-scope locale tracking (set ±U if the POSIX locale variables change within the shell); this is provided as-is, use with care, and especially do not use it in a system shell (with -o posix, it throws a warning when triggered, as it invokes non-compliance).

R56b: The offsetof macro of dietlibc and klibc, which is upstream-buggy, is overridden with GCC 3+ to avoid a warning.

R56: Building with -DMKSH_ASSUME_UTF8=0 no longer causes a known failure in the testsuite. Building with dietlibc or klibc though causes a warning about offsetof and dynamic “command”. You can now choose which UTF-8 locale to use with -U.

R55: make repool needs mksh R55’s bugfix on the host. OS/2 builds with “textmode” (CR+LF as newline) now need -T. Persistent history is now supported by lksh as well, unless explicitly disabled. There were some changes related to the build system.

R54: now installs both manpages (lksh.1 and mksh.1) independent of how it’s called. Several additional compiler flags are attempted. Porters to Harvey-OS and OS/2 should review their patches.

R53a: this is a botched R53.

R52c: prepare to review use of set +o.

R52b: nothing of note, but prepare to review all mksh scripts to ensure they start with export LC_ALL=C soon.

R52: Android can define MKSH_DEFAULT_PROFILEDIR itself but we don’t. We no longer ship the stop alias.

R51: Please review all mksh scripts, such as a skeleton ~/.mkshrc file, for alias safety and security — in case of doubt, contact us. The EBCDIC and OS/2 ports are not finished, but some improvements are already included. CVS snapshots now use ‘j’ ipv ‘i’ making room for one more stable version; after R51, we will release R53, mostly bugfixes, and roll them all up in R50g.

R50f: If you patch mksh, please do not only update the version in check.t (twice) and sh.h but now in mksh.1 as well; thanks!
Please let the mksh developer team review your .mkshrc files for robustness!

R50e: Better portability; no conflict with system headers defining a “tilde” function; no use of ptrdiff_t any more. The old workarounds for static code checkers are gone. NSIG generation works with GCC 5.

R50d: Nothing to note.

R50c: New HAVE_ISSETUGID define. The example Debian /etc/skel/.mkshrc moved. Security release. Details.

R50b: output is now clearer.

R50: now uses $TMPDIR. If you want to build without SSP, define HAVE_CAN_FSTACKPROTECTORSTRONG in addition to HAVE_CAN_FSTACKPROTECTORALL if you have GCC 4.9+.

R49: There is now generated content at build time; it is known that this is beyond the capabilities of some shells such as Coherent /bin/sh. We plan to address this in a later release by rewriting the relevant parts in C, so that a host C compiler will, in addition to a target C compiler, also be required to build mksh.

R48b: Nothing of notewortiness.

R48: We now ship a Windows® icon; just ignore it if you don’t want it. We regularly update dot.mkshrc so you’d better think of a way for your users to get those updates.

older entries

Download the development version via CVS

You can use cvs(GNU) to download the development version of mksh(1), commonly called HEAD (or “trunk” to some). Beware of bugs though we strive to make it installable (at least on MirBSD ☺) at all times.

% env CVS_RSH=ssh cvs -qd co -PA mksh

You might also want to get the printf.c builtin (choose the right version), but this is optional, strongly discouraged and use it only if you really must:

% env CVS_RSH=ssh cvs -qd co src/usr.bin/printf

Installation instructions as above, although the options, CPPFLAGS, etc. might have changed a little in the meantime. In general, you want the following:

% cd mksh
% sh -r

Optionally set CC and other variables, as usual.

Unofficial git mirror

github (chosen only for popularity) hosts a read-only, push-only, possibly nōn-fastforward, unofficial git mirror of the mksh source tree. Use at your own risk.

Users' Upgrade Caveat

This does not necessarily list new features, only these which users should be aware of for existing scripts.

current: The cat and sleep builtins have been removed. In restricted shells, HISTFILE is now read-only. Do not rely on the BOM enabling UTF-8 mode or turning on POSIX mode disabling UTF-8 mode any more, full locale tracking may drop these, and only the LANG and LC_* variables (and manually running set ±U and that being restored upon returning from Korn-style functions) determine UTF-8 mode then. (A preview of this change is already available via Debian bullseye, but more remains to be done.) The Emacs mode editing command capitalize-word[sic!] was renamed to capitalise-word (to fix spelling), prev-hist-word to prev-hist-bigword (consistency with the new bigword commands). Converting variables imported from the environment to integer will discard their value if it isn’t purely numeric, for security reasons (“taint”). The IRC channels moved to a different network. Escaping was improved and thus, for some characters/bytes, changed. Builtins now error out if they returned true otherwise but encountered write errors on stdout. Expect persistent history to require PostgreSQL in the future for reliability. If an environment variable occurs more than once on shell startup, the last match used to win; this is changed to the first for consistency with libc even if this mismatches other duplicate resolution algorithms. The kill-region editing command used to be bound to ^W like in Emacs, but ^W is usually taken by WERASE so it was moved to Esc+^W so users reading the manual page aren’t confused about what it does. The caret notation used by bind changed, see its documentation in the manpage, or the 2021-09-26 IRC heads-up mesaage, for details. Mapping of raw octets in UTF-8 mode will be moved from U+EF80‥U+EFFF to U-001BBB80‥U-001BBBFF (out of the PUA and past anything actually occupied by UCS) for R60, when moving from OPTU-16 (UTF-8 and CESU-8) to 21-bit UTF-8. Value substitutions now handle exit (also set -e, etc.) correctly; function substitutions still don’t for AT&T ksh93 compatibility. BOM (byte order mark) handling removed. A subtle change to the hash algorithm (affects both ${var@#} and the Lbafh_* functions in dot.mkshrc) delivers better performance but no overall degradation in avalanche / quality; the hashes of anything not a single byte change from older releases’, though. lksh LONG_MIN/-1 now properly raises an implementation-defined signal (SIGFPE on MirBSD) if the result is > LONG_MAX. Escape a caret if it is the first character in a shellglob group [\^a-z] since the unescaped meaning may be changing to [!a-z] at some point. Read the FAQ and TFM! dot.mkshrc also adds ~/.local/bin/ to $PATH if it exists. ulimit options -v and -m now honour both POSIX’ and NetBSD®’s assumptions in all possible cases. (unfinished…)

R59c: On Mac OSX 10.4 and up, ulimit -m is now an alias for ulimit -v, which was the one older versions had (so pkgsrc® can use it consistently). Some changes to path normalisation and here document handling might introduce breakage, but we hope they only correct things ☻ Also, read the FAQ.

R59b: The output format of set +o changed.

R59: On OS/2 the test/[/[[ builtins now add executable file extensions to several more checks. The output of some commands changed adding quoting for re-entry safety. Restricted mode is now enabled if the shell is called as rmksh, rsh, rlksh, …. The right-hand side of a string comparison (=, ==, !=) in [[…]] now uses full Korn Shell extglobs (breaking, but eliminating the need for many eval). There’s now a which function in dot.mkshrc. The global builtin is gone (use typeset -g from R55+ instead), breaking.

R58: HISTSIZE is now limited to 65535, as pre-announced for years. Running set -p interactively in privileged shells obtains the effective privileges.

R57: Bugfix / rollup release, with only a few changes — it has some known bugs; no (known) regressions though.

R56c: Bugfix-only release; some fixes might cause new warnings

R56b: Bugfix-only release

R56: Aliases support ‘.’, ‘:’ and ‘[’ in names again (though “[[” is still forbidden). POSIX character classes and the BSD re_format(7) extensions [[:\<:]] and [[:\>:]] (quoted due to shell syntax issues) have been added (ASCII/EBCDIC only). Some experimental changes to the history code might help with the vanishing entries phenomena. Switching to POSIX mode now disables UTF-8 mode and forces exec to a PATH search and to use execve(2). In dot.mkshrc the hd_mksh function to hexdump using builtins is now always available, and the default editor selection has changed: it’s moved to near the top of the file and now has a priority list users can change.

R55: The POSIX declaration utility concept is introduced, which also applies to commands having variable assignments and redirections preceding them. wait however does not keep assignments any longer. The new \builtin utility forwards the declaration utility flag exactly like command does. The new typeset -g replaces mksh’s previous home-grown global builtin, which is now deprecated and will be removed from a future version. Aliases are now expanded for command, function and value substitutions at parse time (like for functions, and excepting accent gravis-style substitutions), and typeset -f output is alias-resistent; furthermore, alias names are now limited to [A-Za-z0-9_!%,@], following POSIX, although a non-leading hyphen-minus is also permitted. print -R is now (correctly) roughly equivalent to the POSIX mode echo. The deltas between mksh and lksh, and between normal, POSIX and “SH” mode, are now properly documented in the manual pages. The let] hack is gone. ulimit -a output changed to display the associated flag. $PATHSEP is now pre-defined to ‘:’ (‘;’ on OS/2). $LINENO is now incremented better in eval and alias expansions.

R54: Lazy evaluation side effects and set -e-related error propagation in || and && constructs are now handled properly.

R53a: Tilde expansions of parameters (~, ~+, and ~-) now strip . and .. components from their results. The sample PS1 in dot.mkshrc was corrected for users whose home directories are præficēs of others’. Rotation operators were renamed from <<< and >>> to ^< and ^>. var=<< may now be used. Many fixes.

R52c: Prepare to audit all uses of set +o. Handling of "`\"`" is now considered not a POSIX violation, until this issue is officially resolved. Our PDF manpages now use the PA4 paper size enabling printing without the need to scale of crop on both DIN ISO A4 and USA “letter” paper. The manpages now compile with an older version of the mdoc macropackage (in use by e.g. Schillix) installed. command -pv and command -pV now behave POSIX conformant.

R52b: Prepare to audit all scripts to ensure they begin with export LC_ALL=C as we’ll implement locale trackiing some day. Handling of "`\"`" is now again not POSIX-compliant even in posix mode to unbreak existing code (Austin#1015, mktexlsr). set -C; :>foo is now race-free. Some bugfixes.

R52: (( … )) is now a compound command, which changes the way I/O redirections work. ${x#~}, ${x/y/z}, etc. now have tilde expansion enabled. ${x//#y} no longer works, for anchored patterns use only one slash; quotes are now honoured better in such expressions, though. alias stop='\kill -STOP' is no longer defined by default anywhere; source is no longer an alias but a built-in utility, unbreaking it in some cases; the lksh hack to remove an alias upon function definition is removed. issetugid(2) is no longer used for set ±p checks, unbreaking suid in some cases. Handling of "`\"`" is now POSIX-compliant (this breaks scripts)! More bugfixes, although there are (sorry!) still some known bugs ☹

R51: Integers with bases outside of the permitted range are handled as base 10 instead of failing to parse, like ksh93. Korn shell style functions (function foo {) now have locally scoped shell options (e.g. set -o noglob) except in lksh. Much standard code is now protected from being overridden by aliases; the new enable function in dot.mkshrc can be used to enable or disable a built-in utility (such as rename) or function (including those in dot.mkshrc) by means of an alias. The feature to unalias an identifier when a POSIX-style function with the same name is defined only persists in lksh, as it is a legacy feature. cat(1), when a flag is given, and printf(1), now prefer an external utility over the builtin reliably. Several bugfixes, such as command -v now handling shell reserved words, impact compatibility.

R50f: unset HISTFILE actually works. Several more bugfixes and robustness improvements. The mksh(1) manpage now documents how to enable/disable the UTF-8 mode based on the current POSIX locale according to how it’s done at startup on some OSes.

R50e: Warning: do not use x=<< inside a function, it has never worked.
Lots of POSIX compliance and bug fixes. New options for the exec builtin.

R50d: Fixed a segfault and a regression in field splitting breaking update-initramfs. Sorry! Also, added a warning about not using unchecked user input in arithmetics — [[ $x = +([0-9]) ]] || die is a useful check. We’ll link a more detailed writeup about it later.

R50c: $RANDOM is no longer exported. Field splitting has improved. This version fixes one security issue of low importance (details) which is mksh-specific, and mksh is not vulnerable to all those GNU bash bugs, some of which affect AT&T ksh93 as well.

R50b: nameref can alias $1, etc. again.

R50: Arithmetic expressions are now IFS-split, as per POSIX; this matches what the manpage always documented. Due to regressions, the arr=([index]=value) syntax (naming the indicēs during setting an array) is gone for now, and will not reappear in “set -A”, only in the “=(…)” syntax once we get its parsing fixed. Privileges are now dropped upon start unless the shell is started with “-p”.

R49: The hash algorithm has changed (for, hopefully, the last time); the old algorithms are gone from dot.mkshrc too, and the ${foo@#} syntax no longer accepts a seed value (for more variety use the functions from dot.mkshrc; for hash tables, just xor and rotate the finished stable hash). Some terminal and other issues have been fixed, don’t be surprised.

R48b: Bugfix for multi-line prompts.

R48: The “doch” alias in dot.mkshrc now keeps standard input usable at the cost of the command to be run being logged by sudo(8). If you notice anything unusual (regression) in the interactive display code please report it; sections of that code have been refactored and improved.

older entries

Recent Changes

Changes in the current (unreleased) development version:

R59c bundles tons of bug and portability fixes:

R59b is a must-have bugfix upgrade for R59 (not R58):

R59 has some major fixes, also introducing breaking changes:

R58 contains a lot of fixes and improvements:

R57 rolls up bugfixes, with few hard changes:

R56c is a bugfix-only release everyone must upgrade to:

R56b is a bugfix-only release everyone should upgrade to:

R56 is a bugfix release with some experimental fixes:

R55 is mostly a feature release with summary bugfixes:

R54 is a bugfix release with moderate new features:

R53a is a snapshot/feature release:

R52c is a bugfix-only release:

R52b is a strongly recommended bugfix-only release:

R52 is a strongly recommended bugfix release:

R51 is a strongly recommended feature release:

Changes in the current (unreleased) R50-stable branch:

R50f is a required security and bugfix release:

R50e is a required bugfix release:

R50d is a required bugfix release:

R50c is a security fix release:

R50b is a recommended bugfix release:

R50 is a recommended bugfix release:

R49 is a recommended bugfix release:

R48b is a minor bugfix update:

R48 is a small but important bugfix update:

older changes

Future Plans

MirBSD Logo