Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux keyboard scancode issues: For example, UP ARROW gives ^[[A

We've been struggling for a while now to understand the keyboard scancode behavior in Linux.

When we open a normal bash shell, the arrow keys works as expected: UP shows the previous item in the history etc. However when you spawn a process, arrows does not work as expected anymore. For example, UP prints ^[[A instead of the previous command.

To demonstrate this, do something like:

bash$ ping www.google.com

Now, press UP or DOWN etc. and you will see the wrongly mapped key codes while the process is running. However, when you terminate the process the arrow keys will work again.

We've tested it on CentOs, Ubuntu, Mac and even in different shells (bash, sh, zsh) and the same happens everywhere. I've also tried different keyboard modes using kbd_mode where we tested with RAW and XLATE modes.

The closest thing I could see while searching for answers were IPython users have experienced the same behavior when IPython was not build against readline. However, this is not related to our case as far as I can see.

We are developing a C++ Tcl based console application which uses cin and cout to communicate with, and get input from the user. We are having issues with the arrow keys when we try to access the history of previously entered commands. This is a major issue for us as 99% of people expects the arrow characters to just work.

Any ideas on how we could overcome this would be much appreciated.

like image 527
user2749202 Avatar asked Oct 16 '13 09:10

user2749202


People also ask

What does the up arrow mean in Linux?

Linux should tell you there is no directory with that name. Now type the up arrow key -- the previous command you entered shows up on the command line, and you can use the left arrow to move the cursor just after the capital C, hit Backspace, and type a lower case c.

What is Scancode in keyboard?

A scancode (or scan code) is the data that most computer keyboards send to a computer to report which keys have been pressed. A number, or sequence of numbers, is assigned to each key on the keyboard.

What does the up arrow do when we are at the shell prompt?

up arrow should work and show you the previous commands you typed and used.... Also you can use the history command to go thru the previously used commands...

How do I use arrow keys in terminal?

The way to scroll using the arrow keys in a terminal emulator is to hold down the shift key. This is because a terminal emulator send all keypresses to the application running in the terminal; holding shift down bypasses that. This can also be used with other keys like copy and paste.


1 Answers

You must set the terminal into raw mode to get the scan codes and handle them (that is: disable ICANON, you want the non-canonical mode). You probably also want to disable ECHO (so that it doesn't print your input on the terminal).

That is what readline or linenoise are doing. See here for some code. Esp. see the function linenoiseEnableRawMode. Some other simple sample Python code is here where I have written a simple console media player which checks for the keypresses left ("\x1b[D") and right ("\x1b[C").

The relevant calls are to tcgetattr (to get the current terminal state and modify that state struct to get into raw mode and enable some other useful behavior stuff) and tcsetattr (to set the state).

readline, libedit or linenoise are some libraries which do all that work for you and provide you with history, autocompletion, etc.

At the end, you must restore back the old state, otherwise you get the behavior you are describing in your shell.

like image 103
Albert Avatar answered Sep 21 '22 12:09

Albert