how do I replace the Erlang shell with my own shell?

Matthias Lang <>
Fri Jan 21 13:13:44 CET 2011


I want to write my own shell for Erlang. I want to be able to switch
back and forth between my shell and the regular one without restarting
the VM.

I started off writing my own autocomplete. That's easy: just call
io:setopts([{expand_fun, Fun}]). Details are in the 'io' manpage.

But replacing the shell seems much harder. Two unsatifying approaches:

  1. Write a module called shell.erl, i.e. same name as the one
     shipped by erlang.org, and use code loading to switch between my
     version and the normal one. That would switch _all_ shell
     instances at the same time.

  2. Hack shell.erl and make it provide two variants of shell
     behaviour. I'll then have to merge changes forever.

There must be a better way. Digging through how input comes in, I find:

  First, user_sup.erl starts either of two descriptively-named
  modules: user_drv.erl or user.erl, depending on options. The default
  is user_drv, but any of '-noshell', '-oldshell', '-noinput' cause
  'user' to be started. There's also an undocumented switch, '-user'
  which lets you specify a module. Actual input comes from the 'tty_sl' port.

  user_drv.erl seems to be 600 lines of fiddling. The only feature it
  seems to implement is the ^G menu. The module name 'shell' is hardcoded
  into all of the variants of user_drv:start() which can be called from
  user_sup.

  user.erl seems to be 800 lines of roughly the same thing as
  user_drv.erl.

Conclusion: If I want to write my own shell, I also have to write a
replacement for user_drv. Right?

Matt


More information about the erlang-questions mailing list