SSH server: How can I get raw input from the client?

Good morning folks,
I’m new to Elixir and have a project I’d like to build, but I think I might be a little out of my depth.
I want to make an SSH server which, instead of presenting a command prompt, presents a simple game in the terminal.

I’ve found jbenden/esshd and a couple of small examples of Erlang’s own :ssh module. However, all the examples I can find seem to accept input line by line. The user types a command then the user presses enter, then the full line they typed is sent to the server and my code can read it and do something with it.

I’m wondering if this is a gap in my knowledge about how SSH works. With a normal command-line application, I know there are arcane escape sequences I can send to any given terminal emulator that will put it into raw/non-canonical mode; all nicely abstracted away behind ncurses so I don’t have to think about them.
But in this application, there is no terminal, at least not one I’m aware of.
By what mechanism can I signal to an SSH client that as soon as the user presses an arrow key, I want to hear about it?


Not exaclty grasping if you really want to run your ssh server or you just want to run a custom shell, but it will be probably worth reading on:

  • terminal emulator
  • shell (eg bash)
  • ANSI escape codes

It seems that you just need to run standard ssh but have a different shell (then bash) set for a user.

The special codes that are sent by the shell app are interpreted by you ur terminal emulator (eg gnome terminal) and the SSH server just passes them through as strings.

1 Like

Hi Marcin! Thanks for your suggestion.
I should clarify – for the sake of security, and the simplicity of the design, I don’t want to just make a custom shell and put it behind sshd.
I want to use the SSH daemon module included with OTP; that way the server and all the application logic can be part of the same application, and I could handle many concurrent clients in parallel as separate processes.

I have looked at ANSI escape codes, but to the best of my knowledge there’s no way to put a terminal into non-canonical mode using escape sequences alone. The thing that seems to do what I need is termios, but I’m not sure how that’d work over SSH, or how I could interface with it from Elixir.