How do you exit out of erl and iex?

How do you exit out of erl and iex? ctrl-G does not work. ctrl-c two times work but any single command inside prompt is better.

1 Like

In erl and iex you can use :init.stop

In erl you can use the shorthand q()

1 Like

erls q/0 works in iex as well, though you need to qualify it: :c.q() IIRC.

:init.stop/0 is not always what you want, as it takes the full BEAM down, similar to how C-c C-c does. I’m not sure if C-g q RET does keep things alive or if it shuts down as well.

q/0 does not work nor :c.q()

none of those work.

It works for me:

$ iex
Erlang/OTP 22 [erts-10.5.6] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :c.q
:ok
iex(2)> %                                                                                                                                                                                                                                                       $ 

Where the % is an EOF marker put in by my shell, as it received an EOF without a preceeding newline.

1 Like

ctrl+\ works for me under MacOS and linux? (i believe this is sending a SIGQUIT signal to the process)

4 Likes

You can also do ctrl-G followed by a q. After you have done ctrl-G you can also play around with starting new shells, or tasks, on the same node, running remote shells on other nodes and switching between them.

Though iirc iex doesn’t seem to like it if you try and start multiple elixir shells on one node.

10 Likes

Wow, I did not know this feature. I found that I can create a new job and it is actually an erlang shell, not an elixir shell, but within the same runtime so I can start processes from elixir and then call them with erlang code. Very cool to paste both languages code chunks for debugging.

You can start multiple erlang shells and other “jobs” as well. The s command can take an argument which is a module name (in erlang syntax) and it will then call module.call(). The default i/o of the jobs is buffered so you only see the i/o of the job you are connected with.

It is sort of like having multiple windows in an OS but without the windows. :smile: That was the general idea anyway way.

I don’t know why multiple instances of the Elixir shell cannot be run. If you try and do

--> s 'Elixir.IEx.CLI'

then the whole system blocks and you have to terminate the system with ctrl-C. Which is a real shame.

For a better description check out http://rvirding.blogspot.com/search/label/Programming%20and%20Erlang . In the first blog about the erlang rationale there is a link to a paper I wrote on the Erlang rationale and towards the end of it their is a description of the i/o system and of “Process groups, Jobs and JCL” which is what this is. Calling it “JCL” was a joke.

Sorry, wandering a bit here.

EDIT: The Erlang shell is not really anything special from the system’s POV, it is just a normal process which doesn’t do anything strange or special or blocking or weird. That is why you can run multiple shells.

4 Likes

Hey thank you, I will definitely read that !

Is there a way to call local_start instead of call from the s command ?

User switch command
 --> j
   1* {'Elixir.IEx.CLI',local_start,[]}

I have some iex helper functions in ~/.iex/my_helpers.ex:

defmodule MyHelpers do
  @moduledoc "This module contains `iex` helpers."

  @doc "Exit the `iex` shell."
  def xx, do: System.halt

  @doc "Exit the `iex` shell."
  def exit, do: xx()

  @doc "Observer."
  def ob, do: :observer.start()

  @doc "Recompile."
  def re, do: IEx.Helpers.recompile()

  @doc "Clear screen."
  def cls, do: IEx.Helpers.clear()
end

To compile: cd ~/.iex && elixirc my_helpers.ex

3 Likes

Sounds like a Bug. ^.^

1 Like

There is a section on the docs about exiting: IEx — IEx v1.16.0

We don’t mention :c.q, :init.stop and friends because those would disconnect live nodes.

It should be s 'Elixir.IEx'. There are docs here: IEx — IEx v1.16.0

4 Likes

Ah, thank you. That’s what you get for not reading the documentation. :smile: I had just assumed it was the same function as the initial one was started with.

Now that I have you here: why are there no equivalent shell functions in iex corresponding to the erlang shell functions i(), m(), l() and regs() which are so useful when working with systems? I know you can call them through the :c module but that is not the same thing. Or have I missed some documentation again? :wink:

i() for listing running processes, m() for listing loaded modules, l() for (re)loading a module and regs() for listing registered processes.

EDIT: I now see that l() exists.

2 Likes

Yeah, we hid the initial one (I didn’t know we could actually see it via Ctrl+G) and made the official API shorter.

As you said, we have l but we don’t have i and regs, which indeed could be useful. But what is the use case for m?

2 Likes

But what is the use case for m ?

I guess checking if a module was loaded from the right beam file.

I use System.stop before. But :c.q and ctrl+\ seems more handy

Well m() lists all the currently loaded modules and from where they are loaded. m(mod) gives information about the load module which is basically the return from mod.module_info() but formatted for display. It is a way to show more basic information about a module, what is actually in the module and not “just” the documentation.

A common use is as @lud wrote to see which beam file you are actually using. It is not difficult when working to get the wrong version of a module loaded.

Unfortunately it loads the module if it is not loaded.

2 Likes

Thank you! All this time I have been doing ctrl+c+a+enter :woman_facepalming: