I'm writing a CLI in elixir, how can I prompt the user for a password, without displaying the input in the terminal?
3 Answers
You can accomplish this using the Erlang :io.get_password()
function, e.g.
IO.write("What is your password?")
password = :io.get_password()
|> List.to_string()
Note that IO.write/1
is preferable to using Mix.shell().info()
for the prompt because the info
function will add a newline, which is usually not what you want in a prompt.
Also be advised that :io.get_password()
returns input as a charlist, so you will probably want to convert it to a binary as demonstrated above.
I wrote a package that utilizes the above technique: https://hex.pm/packages/cowrie

- 8,746
- 5
- 35
- 49
Apparently there are some problems with this. Currently the best solution seems to be to repeatedly clear the input in a loop, as implemented in the Hex package manager:

- 53,604
- 17
- 144
- 168
-
Fair enough. There might not be a good platform independent way to do it via the VM. – Baruch Jun 09 '16 at 11:03
-
1You might also have some luck using `:io.get_password` from OTP, but I remember that I couldn't get it to work properly. I think it follows a similar approach. – Patrick Oscity Jun 09 '16 at 13:31
Just borrow the functionality directly from Mix.Tasks.Hex
, by writing some code like the following,
some_pass =
Mix.Tasks.Hex.password_get("Password: ")
|> String.replace_trailing("\n","")
And if you are requesting the password in a task, and don't want to keep asking for it over and over, you can save it in an environment variable like this,
:os.putenv(String.to_charlist("SECRET_PASSWORD"), String.to_charlist(some_pass))
And, of course, retrieve it with:
System.get_env("SECRET_PASSWORD")

- 379
- 4
- 7