2

I am trying to get user input into python. However if a user uses a key such as [Home] or Ctrl+A or Ctrl+k (typical shell commands) they get a character representing that key rather than the expected behaviour.

I currently have:

data = input("Enter your data here: ").strip()

However if the user uses the Ctrl+A to go to beginning of line, they instead get a ^A character printed on the screen as part of their input.

Is there a way for me to get input in a way that would allow the user to use bash key combos like Ctrl+A?

1
  • 5
    import readline at the top of your script. Commented Sep 17, 2014 at 22:42

1 Answer 1

2

The short version is to just add import readline to the top of your script, and it will magically work.

More specifically, the readline library provides a wrapper around libreadline, which is the same library that lets your bash shell, or the Python interactive interpreter, for that matter, do fancy input editing.

So, you could use readline directly. If you want to do anything fancy, you should read the docs, and also see rlcompleter.

But for simple cases like this: by default, just importing readline will (in effect) patch input for you,* and that's all you need.

So, assuming the user (and his distro) are using default settings, they will be able to use the same emacs-style keystrokes they use in bash. (And, if they've changed the settings, presumably they want to be able to use those settings in your program, not just in bash.)


The only problem is that this only works if libreadline was present when Python was built:

  • On most Linux and *BSD systems, this isn't an issue.**
  • On OS X, it would be an issue, but Python provides a workaround that uses BSD libedit instead, which Apple includes.***
  • On Windows, if you're running inside a normal cmd.exe "DOS box", you automatically get DOS-style line editing, and can't get anything better... but fortunately, Windows users don't know what they're missing. :)

* If you're wondering how it works under the covers, the code underlying input is cleverly designed to be hooked by both readline and IDLE, in a way that's flexible enough that you can even do nifty things like integrate it into an asyncio event loop. So, readline doesn't really patch input; instead, it just registers a hook. Which is cool, and worth reading the source for, but it's not relevant to your question.

** And if it is, there's not much you can do about it except just install libreadline and rebuild Python. On *BSD, I guess you could configure Python to build the OS X libedit wrapper, but I don't know why you'd bother.

*** If you're using a pre-built Python from Apple or (until recently) python.org, you'll be using this workaround. Most apps and most users won't be affected by the difference, but there can be some annoyances with it. The way to force a solution to those annoyances is to depend on a newer version of readline off PyPI, which will fail if your users haven't installed libreadline.

Sign up to request clarification or add additional context in comments.

4 Comments

Absolutely love the added info about how this behaves on different systems
@Humdinger : If you like readline, you should read about rlcompleter. That doc gives an example script that gives you TAB completion in the Python interactive shell, which is very handy, IMHO. Also see the Python tutorial
@PM2Ring Thanks for the share! For this specific project, it has no use to me, but I am sure I might use it in the future!
@PM2Ring: Thanks. I should probably have mentioned rlcompleter in the answer too; I'll rectify that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.