How to make CLI command cache working? (busybox feature)

In Arokh's OpenWRT FW when I used the up arrow, even after a restart of the router, the previous commands used in the CLI popped up. Now in a build I use here, it does not, I already installed BASH, but that doesn't seem to make a difference, anyone got any pointers on it?

I already tried searching on Google, but couldn't find anything useful, except for BASH and that doesn't work for me. Maybe I am not using the correct search string, but still, would love to get that function back.

2 Likes

You need to re-compile busybox with the correct options.

I have done this in my own build, as I have wanted the command history to save between sessions while the router is running, but I am not writing the history to flash, so the history is only in RAM /tmp:

Manually set busybox options into .config:

CONFIG_BUSYBOX_CUSTOM=y
CONFIG_BUSYBOX_CONFIG_FEATURE_EDITING_SAVEHISTORY=y
CONFIG_BUSYBOX_CONFIG_FEATURE_EDITING_SAVE_ON_EXIT=y

(You can do that also in menuconfig)

Like said, I have patched busybox to avoid writing to flash. By default it would save to the file specified by HISTFILE env variable or secondarily to the root's HOME directory:

--- /dev/null
+++ b/package/utils/busybox/patches/310-save-history-in-tmp.patch
@@ -0,0 +1,12 @@
+--- a/shell/ash.c
++++ b/shell/ash.c
+@@ -13531,7 +13531,7 @@
+ 		if (iflag) {
+ 			const char *hp = lookupvar("HISTFILE");
+ 			if (!hp) {
+-				hp = lookupvar("HOME");
++				hp = "/tmp";
+ 				if (hp) {
+ 					hp = concat_path_file(hp, ".ash_history");
+ 					setvar0("HISTFILE", hp);
+

If you want to save to flash, just toggle that config option in menuconfig, skip the patch and then define HISTFILE in your router user profile.

EDIT:
added the comment that you also need to explicitly first say that you want to compile busybox with custom options. Devs want to prevent easy toggling of busybox options, so they are hidden behind a selection of going into custom...

3 Likes

Would that be worth writing it down in a howto, e.g. https://wiki.openwrt.org/doc/howto/busybox.save.history?

1 Like

Hey there.

Bash comes with default bash history configuration. So maybe just install bash and use it instead of ash?

If you decide to point roots default shell in /etc/passwd, better make no mistake. Entering something invalid will prevent you from connecting by SSH and you'll need a serial interface to repair.

I just tested this in Virtualbox but I'd expect any regular router to be equally capable.

If you don't want to adjust /etc/passwd (which is dangerous, as I explained), you can just call ssh with bash as alternate login shell by ssh root@hostname -t "/bin/bash -l".

Regards,
Stephan.

2 Likes

I'd like my history to save across reboots but I'm totally lost what to do. Can you explain it a little more for idiots like me? Thanks!

All you need is CONFIG_BUSYBOX_CONFIG_FEATURE_EDITING_SAVEHISTORY, it'll save to /root/.ash_history by default and persist through reboots. You could also make it persist through upgrades with this command before building:

mkdir -p files/lib/upgrade/keep.d ; echo /root/.ash_history > files/lib/upgrade/keep.d/custom

You just need to compile busybox with that option set.

So this is the confusing part. How do I actually compile busybox?

In the Openwrt/LEDE build system (runing on Linux)
https://lede-project.org/docs/guide-developer/build-system

So, this is not something that you can change in a running system, but you really need to compile from source code.

Ah ok that makes sense. Thanks for helping a newb.

may also want:

CONFIG_BUSYBOX_CONFIG_FEATURE_EDITING_SAVE_ON_EXIT=y

the simplest solution that I found, is just don't using ash anymore but
Switching to Bash / setting up .bashrc
OpenWrt comes with Ash shell. If you would like to use Bash instead, here is how you can switch and add some nice colouring to it. Install Bash by issuing the following:

1 opkg update
2 opkg install bash

Then edit /etc/passwd and change the root user line to this:

1 root:x:0:0:root:/root:/bin/bash

After that, run this command (which will create /root/.bash_profile and put “. $HOME/.bashrc” in it):

1 echo ". $HOME/.bashrc" > /root/.bash_profile

I'd strongly recommend not to configure bash in /etc/passwd, but to enter it manually when connecting via ssh. The background for this advice are sysupgrades, bash is not part of the default firmware images - meaning it won't be preinstalled after a sysupgrade (unless you build OpenWrt with it included), preventing you from being able to log into your router (no valid shell, until you reinstall bash again).

3 Likes

fixed this by the following line in /etc/rc.local

test -x /bin/bash && sed '/^root/ s_/bin/.*_/bin/bash_g' -i /etc/passwd || sed '/^root/ s_/bin/.*_/bin/ash_g' -i /etc/passwd

when after a system upgrade bash is not available, it automatically switch back to ash, and also back to bash when it is installed :slight_smile:

3 Likes