Down the iex rabbit hole - the mysterious erl "-user" option

310 views
Skip to first unread message

Scott Thompson

unread,
Oct 28, 2015, 2:15:15 AM10/28/15
to elixir-lang-talk
I was interested in implementing my own tool with a command line prompt so I thought it would be instructive to see how iex starts up and does its thing.

This led me to a multi-hour investigation of iex which was rather odd.  It appeared that when iex starts it simply loads IEx.App which does little more than load IEx.Config -- an agent that stores configuration information.

It wasn't until I realized that the iex command itself was a shell script that I saw how iex really starts up.

exec "$SCRIPT_PATH"/elixir --no-halt --erl "-user Elixir.IEx.CLI" +iex "$@"


So the command line calls elixir which passes the '-user' flag to Erlang with a module name that seems to be where the main body of the code that boots up iex is found.  This, in turn, eventually fires up IEx.Server which looks like the beast that is actually printing the prompt, accepting user input, etc.

My question is, what is the mysterious "-user" flag?  I looked through the Erlang documentation on the erl command.  It doesn't appear to be captured by the init module.  It's not listed as a flag in the 'erl' command itself.

I assume that this flag actually asks Erlang to use the Elixir.IEx.CLI module as the user shell to handle commands?  Is it documented and if so, where?

Jim Freeze

unread,
Oct 28, 2015, 8:33:10 AM10/28/15
to elixir-l...@googlegroups.com
I'm no expert, but I think that -user could be a "user" flag.

When starting the Erlang runtime system, arguments are divided into emulator flags, flags and plain arguments.

"The init process itself interprets some of these flags, the init flags. It also stores any remaining flags, the user flags. The latter can be retrieved by calling init:get_argument/1."



Then the docs for IEx.CLI module say

  In order to work properly, IEx needs to be set as the
  proper `-user` when starting the Erlang VM and we do so
  by pointing exactly to this function.

  If possible, Elixir will start a tty (smart terminal)
  which makes all control commands available in tty
  available to the developer.

  In case `tty` is not available (for example, Windows),
  a dumb terminal version is started instead.

This may be helpful, but the docs don't say why the user change produces 'proper' working of erlang, or what 'proper' is.

Jim



--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/cbdf2da4-9bce-4aca-9046-bdec43ac4d4c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Dr. Jim Freeze, Ph.D.

José Valim

unread,
Oct 28, 2015, 8:42:36 AM10/28/15
to elixir-l...@googlegroups.com
I was interested in implementing my own tool with a command line prompt so I thought it would be instructive to see how iex starts up and does its thing.

I wouldn't use IEx as an example, to be honest, because as you find out it has a bunch of other concerns like setting up the user process for all IO in the system. Here is a great explanation of how it all works and why there is such complexity (for example to allow multiple sessions):


If you would like your own command line prompt, IO.gets can get you really far. If you want key bindings, then you need tty and I think elixirsips has episodes on it. Or you can check other projects like ex_top: https://github.com/utkarshkukreti/ex_top

Josh Adams

unread,
Oct 28, 2015, 9:19:10 AM10/28/15
to elixir-l...@googlegroups.com
If you want a raw bit of code that mentions tty_sl, which is what Jose is talking about, you can see the ExTris CLI module here: https://github.com/knewter/extris/blob/master/lib/extris/cli.ex#L8

There's not a whole lot of documentation around that binary, but the C implementation is here: https://github.com/erlang/otp/blob/maint/erts/emulator/drivers/unix/ttsl_drv.c

If you want to see Robert Virding mention how LFE uses ttyl_sl: http://erlang.org/pipermail/erlang-questions/2011-January/055946.html

If you want to geek out over TTYs in general:


--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Josh Adams

Scott Thompson

unread,
Oct 28, 2015, 12:45:32 PM10/28/15
to elixir-lang-talk
Thank you, Jim.  I had gotten as far as all that. :-)  

I eventually found the code, in the Erlang source, that actually checks the flag.  It's in a file called user_sup.erl which appears to be a mechanism which allows you to replace the "user" module which it would appear is the module that actually implements the Erlang REPL.

While not directly related to getting my original project implemented, looking through all this stuff has certainly been educational which was the whole point anyway :-)

Scott Thompson

unread,
Oct 28, 2015, 12:47:06 PM10/28/15
to elixir-lang-talk, jose....@plataformatec.com.br
Ah perfect.  That link explains quite a lot.  

The iex investigation, while starting out as a means of looking at a shell-like system turned into an interesting academic exercise if itself which was quite fun.  Thank you for the helpful link!

Scott


On Wednesday, October 28, 2015 at 7:42:36 AM UTC-5, José Valim wrote:
Reply all
Reply to author
Forward
0 new messages