Questions tagged [mksh]

MirBSD Korn shell, or mksh, is a Free command interpreter (shell) intended for both interactive and shell script use. `mksh` is the default shell on Android, some BSDs and some Embedded Linux distributions, and it is available for most other operating systems. Please use the “ksh” tag for generic Korn Shell questions, and the “mksh” tag (additionally) if your question targets mksh specifically.

About mksh

MirBSD Korn shell, or mksh, is a command interpreter (shell) intended for both interactive and shell script use. Its command language is a superset of the Bourne/POSIX shell (sh) language and largely compatible to the original Korn shell (ksh88).

The MirBSD Korn Shell aims at being a compact, consistent, fast, not bloated but also nice to use, shell both for interactive and script use. While some advanced features of other shells (such as programmable/configurable tab completion) are not available, and some design choices have been made to keep it small, many features of other contemporary Unix shells (GNU bash, AT&T ksh93, and zsh) are available; mksh aims at providing the same features on every system it runs on, if at all possible, to aid people trying to script portably (but willing to require a specific shell).

mksh is OSI approved Open Source Software™ and the actively developed successor to pdksh and the default shell on Android, some BSD variants, and some (mostly Embedded) Linux distributions. It is also available for most other operating systems and distributions.

External Links

FAQ

POSIX

mksh is actively developed, as is the POSIX standard; when something in the latter changes, mksh is usually adjusted to match, independent on which version of the standard is currently published.

Because mksh is developed as portable shell, as opposed to integrated within one operating systems, its mission was decided to behave consistent across operating systems (so shell scripts can expect a consistent runtime behaviour), even ignoring POSIX when needed to achieve this. As an example, arithmetics – echo $((2147483647 + 1)) – always use 32-bit integers and define how overflow is handled.

In places where POSIX differs, there are two “knobs” to bring mksh closer to POSIX. One is set -o posix, which changes some run-time behaviour of the shell (and, as a side effect, turns off brace expansion by default). The other is to use the lksh binary which most distribution packaging of mksh should offer, instead of the mksh binary; in lksh, arithmetics are done POSIX-conformant, i.e. with the host’s C long data type, and overflow being Undefined Behaviour.

For details on the differences between mksh and lksh, and between running without and with set -o posix, please refer to the manual.

Pipes: a=u; echo x | read a; echo $a

POSIX allows a shell to run both sides of a pipe in a subprocess – making this equivalent to a=u; (echo x) | (read a); echo $a – or just one. mksh does the former.

If you really need to read out of a pipeline into the current execution environment, you can redesign your program to do things differently, or use a coprocess: a=u; echo x |& read a; echo $a

Process substitution

The GNU bash extension <(command) is not yet supported natively (although it’s on the TODO list). For now, this answer has a workaround.

Locales (POSIX)

Because mksh is developed independent of any widespread operating system and portable to many weird and/or ancient ones, we cannot use the OS’ locale functions. mksh implements the C (POSIX) locale, and a “UTF-8” locale. Which one is active is, currently, independent of the POSIX locale parameters but selected with set ±U (set ±o utf8-mode); this will eventually change.

To make mksh (or lksh) use UTF-8 mode if the current POSIX locale is UTF-8, and C mode otherwise, use: set -U; [[ ${LC_ALL:-${LC_CTYPE:-${LANG:-}}} = *[Uu][Tt][Ff]?(-)8* ]] || set +U

If you need to integrate this into an sh script, run that code only if the script is being run by mksh or lksh:

case ${KSH_VERSION:-} in
*MIRBSD KSH*|*LEGACY KSH*)
        case ${LC_ALL:-${LC_CTYPE:-${LANG:-}}} in
        *[Uu][Tt][Ff]8*|*[Uu][Tt][Ff]-8*) set -U ;;
        *) set +U ;;
        esac ;;
esac

In near future, mksh will track those environment variables itself though.

Octal integers (POSIX)

POSIX has changed to require integers with a leading 0 to be interpreted as octal digits; this breaks scripts left and right. mksh supports either:

$ echo 1: $((010)); set -o posix; echo 2: $((010))
1: 10
2: 8

Command line history

Persistent history is disabled by default, for privacy reasons. To enable it, set HISTFILE to the path of a pdksh-style (binary) history file. Do not use a bash-style (ASCII) history file, as it would be overwritten and corrupted. You may also wish to set HISTSIZE, but not to insanely high values, as the memory is preallocated. You can put this into ~/.mkshrc:

export HISTFILE=~/.pdksh_history HISTSIZE=65536

The persistent history file is shared between parallel shell sessions; synchronisation happens on pressing Enter after a command.

Some mksh binaries are not compiled with support for persistent history, e.g. Android’s (because of the phone-specific environment) or for operating systems without mmap. It will simply not create the file then.

AT&T Korn Shell compatibility notes

Similar to ksh93, functions defined with the function keyword, as opposed to the name() syntax, have their own shell flags (in recent versions); this means you can e.g. toggle UTF-8 mode inside the function, and it’s restored upon leaving it.

Unlike ksh93, however, local variables work in both kinds of functions, and mksh (like all other nōn-AT&T-ksh shells) uses a nested scoping model (meaning local variables of the caller are available to the callee). namerefs are implemented slightly differently: they resolve to the target each time they are invoked/used, not at definition time, so they can refer to the function’s own local variables if not careful.

The DEBUG trap and handling of the ERR and EXIT traps in functions (from ksh88) are not implemented yet; floating-point handling will not be implemented. Several post-1993 ksh93 extensions are not implemented yet, some will eventually be.

Associative arrays

… are on the to-be-implemented list. mksh/assockit.ksh in the “shellsnippets” repository contains a currently-usable (if occasionally a tad slow) workaround by means of shell functions; mksh/assoldap.ksh is a good usage example (LDAP bindings for shell).

When invoked as /bin/sh

… on some operating systems (e.g. MidnightBSD, Debian), a compatibility mode is invoked. This involves turning on set -o posix (better POSIX compatibility), set -o sh (legacy script quirks), or both. This can change the behaviour.

Reporting bugs, mailing list, further resources

The IRC channel #!/bin/mksh on the IRC network Freenode is where you can ask questions, report bugs, etc. – there’s usually some volunteer/user around, and the developers read the backlog most of the time. You can also ask in #ksh (Infopage) if you indicate you’re using mksh. There’s also a mailing list (see the bottom of the manpage) which you can read online, e.g. via GMane.

Since many people learn programming by looking at others’ code, the Shell-Toolkit (shellsnippets) project aims at collecting some. More resources are found in the #ksh infopage.

11 questions
9
votes
3 answers

How to measure time from adb shell with milliseconds resolution?

How can I measure time from adb shell with milliseconds or nanoseconds resolution? Usingdate +%.%N from adb shell returns 1401546811.N (seconds resolution) instead of something like 1401547289.231869798 (nanoseconds resolution). How can I get either…
22332112
  • 2,337
  • 5
  • 21
  • 42
6
votes
3 answers

Have aliases in adb shell non-interactive mode

Hi I need to run things in the form of adb shell When I test everything out inside adb shell, it works because I was able to set some aliases in .bashrc. However, when I do adb shell , nothing works because .bashrc is not used…
m126531
  • 265
  • 1
  • 3
  • 11
5
votes
4 answers

Android Shell EOF

I have a small problem with a script that I am making for Android. I can't seam to get 'EOF' to work in 'mksh'. It is working fine in 'sh' and 'bash', but since 'mksh' is becomming the most used in Android I really need for it to work in all. cat…
Daniel B
  • 1,205
  • 14
  • 18
1
vote
1 answer

The variable $? does not work on $PS1 on mksh

I want my prompt to show the exit status of the last command, so I set my PS1 to this: PS1="$? > " But it always prints 0 >. Even when I run false, for example, the prompt does not prints 1 > or whatever the exit status is. Why does this…
Seninha
  • 329
  • 1
  • 12
1
vote
1 answer

how to make filename match in mksh case insensitive

I'm using mksh (the MirBSD Korn Shell) on Windows 10. I'm used to the old UWin ksh not caring about case on Win7, and have been tripped up several times when 'ls' doesn't see a file because of casing: PC> ls *old ls: cannot access '*old':…
murspieg
  • 144
  • 2
  • 14
1
vote
2 answers

Using "printf" for hex values in android shell

I am porting my shell script (quite big shell script) from bash to android shell (mksh shell). In Android, printf does not seem to be working the same way as it works in other Linux systems. Sample code : $ cat sample.sh ... func1() { A=100 …
Sandeep
  • 18,356
  • 16
  • 68
  • 108
1
vote
1 answer

Is there a way to slice arrays in mksh?

There is ${name//pattern/string} and ${name:pos:len} for strings but I haven't found any similar documentation for manipulating arrays. So far I've just been using shift and/or unset for simple manipulation. The only other plausible alternative…
Six
  • 5,122
  • 3
  • 29
  • 38
0
votes
2 answers

Having trouble with for loop to iterate over a directory

I'm trying to run this part of my code in a magisk module on android so its using android mksh shell. My goal is to skip the Fontchanger folder in $MODULESPATH since Fontchanger is my module, and if the folder is not fontchanger and it doesn't have…
0
votes
1 answer

adb shell "watch" command to monitor

I am trying to monitor some commands in my adb shell and I could go watch adb shell but the extra time to have to connect up to the shell is killing me. Does the Android adb shell have its own version of watch so I can monitor some…
FrickeFresh
  • 1,688
  • 1
  • 19
  • 31
0
votes
2 answers

What does "Unknown error 517" mean in Android shell?

I'm trying to write to a character device in Android shell. But mksh responds with "Unknown error 517" for a whole range of operations. I've tried to use strace to track down the issue, but its not helpful. This also occurs for a whole range of…
not2qubit
  • 14,531
  • 8
  • 95
  • 135
0
votes
3 answers

adb shell regular expression doesn't work as tested locally

First, sorry if my question is obscure or in an inconvenient format. This is my first post here :D. My issue is that I have a script, let's say test.sh which reads an input, and validates if it's a positive integer (reg ex used from this post: BASH:…
t4kmode
  • 1
  • 4