Elixir: IEx shell history

One of the top features in OTP 20 is shell history persistence. So in the Eshell, you can access history from a previous shell by pressing ↑ and ↓ arrow keys.

Enable Shell History

This feature can be enabled by adding/updating the environment variable, ERL_AFLAGS. ERL_AFLAGS is one of the environment variables supported by ERTS. “The content of this variable is added to the beginning of the command line for erl.”

So, we can export that environment variable:

# in ~/.bashrc (or ~/.zshrc)

export ERL_AFLAGS="-kernel shell_history enabled"

Now, after running source command on the rc file, both erl and iex sessions will persist their shell history.

For more information visit this page

erl & iex catch

One thing to keep in mind is that the shell_history is shared between iex and erl. So, if you’re using both erlang and elixir, it could be a problem:

$ erl
Erlang/OTP 21 [erts-10.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Eshell V10.0  (abort with ^G)
1> 1+1.
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution
$ iex
Erlang/OTP 21 [erts-10.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 1+1. % --- AFTER PRESSING ↑

It’s a good thing to keep in mind. Currently, I don’t see a way of separating ways to overcome this. Maybe a flag in ERL_AFLAGS for "-kernel shell_history_file <filename>" where you can provide a shell_history_file can be a way of keeping erl and iex history separate.

Configure shell history file size

OTP 20 also comes with options for increasing (or decreasing) shell history file size, in order to increase the limit of history that can be stored. This value can be set by using the option shell_history_file_bytes and the value for which is the number of bytes that erl shell should remember.

Default number of bytes is 524288 bytes, which is 512kb. I like having this file up to 2mb. I think size beyond this is hard to manage, which also slows down the history access.

This can be done by exporting ERL_AFLAGS:

# in ~/.bashrc (or ~/.zshrc)

export ERL_AFLAGS="-kernel shell_history enabled -kernel shell_history_file_bytes 2097152"

This enables my erl shell to store history worth 2mb (which is the same as 2097152 bytes)

Getting iex and erl history

Erlang’s erl provides a way to view the shared history. This can be done by using kernel’s h() command.

$ erl
Erlang/OTP 21 [erts-10.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Eshell V10.0  (abort with ^G)
1> 1+1.
2> 2+2.
3> h().
1: 1 + 1
-> 2
2: 2 + 2
-> 4

This is a handy command when you’re trying to use a few commands a bunch of times for erl testing.

Have fun coding with OTP 20 and iex!