4

Android ships with mksh as shell, how can I upgrade to latest version (now R57, mine still on R43)?

Official site https://www.mirbsd.org/mksh.htm offers to compile from source, anyone building ready to run binaries?

9

mksh developer here ☺

The problem with distributing binaries is that the binaries need to be built against the exact same bionic libc as your phone provides, which needs both the libc binaries (as shipped on your phone) and the development headers (only present in the AOSP source tree of the person who built your image).

If you wish to use a generic ARM mksh binary instead, you can use one statically compiled against another libc (such as musl (recommended), dietlibc or klibc). However, these will differ in behaviour from the one shipped by Android:

  • Android has a different default PATH, using something like /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin instead of /usr/bin:/bin
  • Android has different directories for /etc (/system/etc), /tmp (/data/local), and the locations of ~/.mkshrc and default EXECSHELL differ

For these reasons I’d recommend to keep your /system/bin/sh as is and only add a /system/bin/mksh or even /vendor/bin/mksh executable with a newer version if you really need it and use that explicitly in scripts and/or interactively.

If you go to the Debian mksh package page you can download the Debian package for your architecture (arm64 for 64-bit ARM systems, armhf for 32-bit ARMv7 or newer; it’s unlikely you’ll need older ones; 32-bit might work on 64-bit systems but not the other way round), then once downloaded to your local computer, you can extract the package as follows (I’ll use the 32-bit version for this example):

ar x mksh_57-2_armhf.deb
tar xaf data.tar.*
find usr/lib/ -name \*ksh -ls

The last command will list all possible statically-linked-against-not-GNU-libc binaries; for the version 57-2, the output is:

  2633594    184 -rwxr-xr-x   1 user   user     185584 Sep 26 00:52 usr/lib/arm-linux-musleabihf/bin/mksh
  2633596    124 -rwxr-xr-x   1 user   user     126816 Sep 26 00:52 usr/lib/klibc/bin/mksh
  2633595    152 -rwxr-xr-x   1 user   user     152716 Sep 26 00:52 usr/lib/diet/bin/mksh

So, you can choose any of these three binaries; I really recommend using the musl-compiled one (that is usr/lib/arm-linux-musleabihf/bin/mksh, the path differs for arm64) as it’s the most correct and complete C library.

adb push usr/lib/arm-linux-musleabihf/bin/mksh /sdcard/mksh-new
adb shell
su
mv /sdcard/mksh-new /vendor/bin/mksh
chown 0:0 /vendor/bin/mksh
chmod 555 /vendor/bin/mksh

Now, unless another mksh executable is in the PATH before /vendor/bin/, running mksh script.sh or just mksh (or mksh -l for a login shell) will start the newer binary (but not read /system/etc/mkshrc unless you start it as env ENV=/system/etc/mkshrc mksh), but the system boot process will keep using the version it was designed for and tested with. (Newer mksh versions may contain bugfixes that cause scripts relying on those bugs or older interpretations of the POSIX sh standard to fail.)

As I am also the Debian Developer maintaining the mksh package there, you can consider those packages as official Linux/ARM builds of newer mksh versions (although lacking the Android specifics).

If you really need a binary with the Android specifics, I can access a Debian/ARM porterbox and compile mksh from source, with the different definitions (as listed above), manually and provide it for downloading; contact me (by eMail or IRC) if you need that, as it’s manual effort and costs me extra time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.