Linux Essentials - Bash History

Originally published at: Linux Essentials – Bash History – LearnLinuxTV

Bash is the default shell in the majority of Linux distributions, and it has countless features and tricks to make you more efficient. Bash keeps a history of the commands you’ve typed at the prompt, but most people aren’t aware of additional functionality that the history provides you. In this episode of Linux Essentials, Jay describes not only how to use the history command, but also some techniques to make better use of it.


I’m one of “those people” who would trade features for simplicity and less attack surface. I got used to bash and its tricks, like !command-number, or !! and such, so moving to oksh was a pretty hard move for me, but thankfully I got past it. Bash comes preinstalled by default on a lot of systems, but I remove it on mine whenever I find it.

Obligatory neofetch post:

                __.;=====;.__                   biky@bikypi4
            _.=+==++=++=+=+===;.                --------------
             -=+++=+===+=+=+++++=_              OS: Void Linux aarch64
        .     -=:``     `--==+=++==.            Host: Raspberry Pi 4 Model B Rev 1.4
       _vi,    `            --+=++++:           Kernel: 5.10.92_1
      .uvnvi.       _._       -==+==+.          Uptime: 2 days, 21 hours, 22 mins
     .vvnvnI`    .;==|==;.     :|=||=|.         Packages: 736 (xbps-query)
+QmQQmpvvnv; _yYsyQQWUUQQQm #QmQ#:QQQWUV$QQm.   Shell: oksh v5.2.14 99/07/13.2
 -QQWQWpvvowZ?.wQQQE==<QWWQ/QWQW.QQWW(: jQWQE   Resolution: 1920x1080
  -$QQQQmmU'  jQQQ@+=<QWQQ)mQQQ.mQQQC+;jWQQ@'   WM: sway
   -$WQ8YnI:   QWQQwgQQWV`mWQQ.jQWQQgyyWW@!     Theme: gnome [GTK2], Adwaita [GTK3]
     -1vvnvv.     `~+++`        ++|+++          Icons: Adwaita [GTK2/3]
      +vnvnnv,                 `-|===           Terminal: dvtm
       +vnvnvns.           .      :=-           CPU: BCM2835 (4) @ 2.000GHz
        -Invnvvnsi..___..=sv=.     `            Memory: 3592MiB / 7377MiB

The theme and icons are there just because firefox installs them, I actually have no theme or icon pack and have no need for them generally. I may use papirus when opening pcmanfm-qt once in a blue moon.

Back to shells, oksh on Linux is just a port of OpenBSD ksh (oksh). Unlike loksh (Linux OpenBSD KornShell, which sounds weird) which focuses on features and is more popular on linux, oksh is trying to be close to the original, so it has limitations, but less code.

Most people who “outgrow” bash (who aren’t many) usually move to zsh, with even fewer like myself using shells like oksh, ash (busybox), or even crazier who just use non-interactive shells like dash (Debian ash).

The reason why it’s a good move to “outgrow” bash is something called “bashism,” which is the bash way of doing stuff. Things like the command time is a built-in feature of bash, when in other shells, you have to install the binary time to time how long commands take to execute. Other bashisms includes things like arrays, automatic text replace, the “–” operator ("–n" which is the equivalent of “n=n-1”), bash math in general and others.

Bashism is not bad in itself, but when you manage systems that don’t include it, like Alpine Linux, AIX, HP-UX, *BSDs and Solaris, you will have a very bad time. You may be able to add it in some of these, but sometimes you can’t, so you have to learn how to not use bash. Which is actually quite hard if you are used to it.

Keeping things POSIX compliant (or close) makes your life a lot easier when you have to run these commands on other systems.

oksh is not without its own nifty tricks though. I got used to its vim mode, which now I can’t like without, like I couldn’t without bash features. Vim mode is available on other shells too though, including zsh and I believe bash too. I go into edit mode and move around with the home key rows (hjkl), delete using x, remove whole line using double d, move whole words left and right using w and b, delete the word on the left using db, delete word on the right using dw etc. Hit i to go into text mode and type my command.

Bash can do most of these with modifier commands (less efficiently though), like ctrl+ left / right arrow, ctrl+backspace, etc. But that is, if your terminal supports it! oksh just has the mode built-in, so you don’t need terminals to support it. Oh, and don’t get me started when you are in a remote connection and you want to do ctrl+left and the controls are taken over by your remote program (like, if you are using a browser with Guacamole to ssh into stuff) and makes you go back instead of the previous word to the left in the shell. Bash features turn against you! It’s not even funny how many times I fell for that and other quirks that I can’t remember.

Yeah, moral of the story: if bash works for you and you always find it available and the big code base is not a security concern for you, use it and its numerous features, they are there for a reason. If it’s not, then learn to not depend on it always being there for you.

There are pro’s and con’s to most all the various shells. Most servers (certainly not all) I work with use Bash as it’s default shell, so that’s what I use. As you said, keeping shell scripts as posix as possible (keep the bash-ism’s to a minimum) would be wise if you support multiple distributions with the same scripts. However, if your hostclass image defaults to Bash, not a problem.

For production, we keep things as consistent as possible. One is begging for trouble when switching to multiple environments in any sort of large scale operation.


Same, even in non-production, like my home lab. I customize everything to be the same on all systems where I can.

On CentOS / RHEL family, bashism is not usually a problem, because /bin/sh points to bash. But if you test a /bin/sh script on say, a Fedora machine (which also points to bash) and deploy it on Debian, you are in for a big surprise if you use bashism.

Most of the time is good to keep things consistent, but sometimes that’s not possible, so you have to take the differences into account. For example, we had Proxmox VE (so, Debian) and running CentOS 5 (some customers didn’t want to upgrade RHEL 5, so we were stuck with this for testing our software on a similar environment), 6, 7 and 8 VMs and a few physical hardware with 7 and 8. I kept separate lists of hostnames, based on the OS being ran, so that when deploying, I could deploy a script on CentOS 6.10 only (like say changing repo to the vault one), or cat all the hosts lists to deploy or execute commands on all.

Well that’s why the first line of shell scripts should specify which to run:


So that it runs the right shell. :slight_smile:

EDIT: Since things in /bin being officially moved to /usr/bin now, I changed the path…

1 Like

I know, but if you want to run in environments that may not have bash, you use /bin/sh and keep things POSIX compliant, up to and including non-gnuism (gnu coreutils have way more features than other tools, like cat -v and grep -c).