5

Using Terminal Emulator for Android, is there a way to enable a persistent command history?

So far, I've tried the following:

  • initial command of export HISTFILE=$HOME/.mksh_history

  • user mksh profile /data/data/jackpal.androidterm/app_HOME/.mkshrc containing export HISTFILE=$HOME/.mksh_history

  • system mksh profile /system/etc/mkshrc containing export HISTFILE=/data/data/jackpal.androidterm/app_HOME/.mksh_history (though preferably the solution does not involve writing to /system)

I'm able to get other Android shells (ash and bash) to write histories into app_HOME without issue. I'm also able to get mksh to write HISTFILE on Linux without issue.

2

3 Answers 3

4

mksh developer here.

We disabled persistent history for mksh on Android, in order to not tax the flash memory with too many write requests.

You can re-enable it in a custom ROM by setting -DHAVE_PERSISTENT_HISTORY=1 in LOCAL_CFLAGS in Android.mk. You can also recompile mksh like that and copy that onto your ROM, if it’s rooted and the base OS version is the same.

Furthermore, you can copy any statically-linked binary for the same architecture on the phone and use that. The mksh-static binaries in the Debian package, however, also exclude persistent history.

If you really think this feature is worthwhile, persuade Google to enable it; for that, they need to edit mkmf.sh and remove the following lines…

# even the idea of persistent history on a phone is funny
HAVE_PERSISTENT_HISTORY=0; export HAVE_PERSISTENT_HISTORY

… then rebuild Android.mk from it (which they do for every new version anyway).

Oh, and you could ask the Terminal Emulator for Android developer to bundle a version of mksh with history enabled. This is probably no bad idea anyway, as it’ll be newer than what you get in the stock ROMs, and it won’t overwrite the system shell /system/bin/sh, but be available to CLI users.

That all still won’t enable persistent history by default (I’m strictly opposed to it, as it’s a surveillance feature), but enables users to set $HISTFILE themselves to enable it.

3
  • I agree, bundled with Terminal Emulator for Android would really be the proper place. JuiceSSH does it, but with bash instead. Anyways, in the meantime I've just compiled it and copied it over. Thanks for the info!
    – Six
    Jul 26, 2016 at 10:51
  • GNU bash is tricky due to possible licence issues (GPL); also, mksh is much smaller and smoother. Furthermore, mksh builds with bionic (Android’s libc) much more easily, so the bundling has low effort needed. Glad I could help!
    – mirabilos
    Jul 26, 2016 at 10:54
  • "a surveillance feature"?
    – endolith
    Aug 30, 2016 at 18:58
0

To write android shell history to file from android terminal type

history > /path/to/file/history.txt

If you use termux instead of terminal emulator then your history is then preserved.

0

I built a working custom mksh from source on an android device using termux and replaced /system/bin/sh with it (rename or backup /system/bin/sh first). You need to install build-essential in termux then:

wget http://www.mirbsd.org/MirOS/dist/mir/mksh/mksh-R57.tgz
tar -xvf mksh-R57.tgz
cd mksh
mkdir build
cd build
sh ../Build.sh -o CFLAGS="-Wall -Werror -Wno-deprecated-declarations -fno-asynchronous-unwind-tables -fno-strict-aliasing -fwrapv -DDEBUG_LEAKS -DMKSH_ASSUME_UTF8 -DMKSH_DONT_EMIT_IDSTRING -DKSH_VERSIONNAME_VENDOR_EXT=\" Android\" -DMKSH_BUILDSH -D_GNU_SOURCE -DSETUID_CAN_FAIL_WITH_EAGAIN -DHAVE_STRING_POOLING=1 -DHAVE_ATTRIBUTE_BOUNDED=1 -DHAVE_ATTRIBUTE_FORMAT=1 -DHAVE_ATTRIBUTE_NORETURN=1 -DHAVE_ATTRIBUTE_PURE=1 -DHAVE_ATTRIBUTE_UNUSED=1 -DHAVE_ATTRIBUTE_USED=1 -DHAVE_SYS_TIME_H=1 -DHAVE_TIME_H=1 -DHAVE_BOTH_TIME_H=1 -DHAVE_SYS_BSDTYPES_H=0 -DHAVE_SYS_FILE_H=1 -DHAVE_SYS_MKDEV_H=0 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_RESOURCE_H=1 -DHAVE_SYS_SELECT_H=1 -DHAVE_SYS_SYSMACROS_H=1 -DHAVE_BSTRING_H=0 -DHAVE_GRP_H=1 -DHAVE_IO_H=0 -DHAVE_LIBGEN_H=1 -DHAVE_LIBUTIL_H=0 -DHAVE_PATHS_H=1 -DHAVE_STDINT_H=1 -DHAVE_STRINGS_H=1 -DHAVE_TERMIOS_H=1 -DHAVE_ULIMIT_H=0 -DHAVE_VALUES_H=0 -DHAVE_CAN_INTTYPES=1 -DHAVE_CAN_UCBINTS=1 -DHAVE_CAN_INT8TYPE=1 -DHAVE_CAN_UCBINT8=1 -DHAVE_RLIM_T=1 -DHAVE_SIG_T=1 -DHAVE_SYS_ERRLIST=0 -DHAVE_SYS_SIGNAME=1 -DHAVE_SYS_SIGLIST=1 -DHAVE_FLOCK=1 -DHAVE_LOCK_FCNTL=1 -DHAVE_GETRUSAGE=1 -DHAVE_GETSID=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_KILLPG=1 -DHAVE_MEMMOVE=1 -DHAVE_MKNOD=0 -DHAVE_MMAP=1 -DHAVE_FTRUNCATE=1 -DHAVE_NICE=1 -DHAVE_REVOKE=0 -DHAVE_SETLOCALE_CTYPE=1 -DHAVE_LANGINFO_CODESET=1 -DHAVE_SELECT=1 -DHAVE_SETRESUGID=1 -DHAVE_SETGROUPS=1 -DHAVE_STRERROR=1 -DHAVE_STRSIGNAL=0 -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 -DHAVE_SYS_ERRLIST_DECL=0 -DHAVE_SYS_SIGLIST_DECL=1 -DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=571 -DMKSH_DEFAULT_PROFILEDIR=\"/system/etc\" -DMKSHRC_PATH=\"/system/etc/mkshrc\" -DMKSH_DEFAULT_EXECSHELL=\"/system/bin/sh\" -DMKSH_DEFAULT_TMPDIR=\"/data/local\" -static -PREFIX=\"/system\""

Got most of the compile flags from here. After that, edited /system/etc/mkshrc to include export HISTFILE=/sdcard/Android/.mksh_history. This was a permanent solution so it worked with remote adb shell and persistent after reboots. You could copy the binary to terminal emulator home folder and set it as the shell command but ~/.mkshrc ~/mkshrc ~/.profile does not appear to work so you will also need to add export ENV=/sdcard/Android/.mkshrc to /system/etc/mkshrc. Download the compiled binary here. sh for android with history enabled

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .