Wait for a keypress before continuing?

peter peter.mosley at talk21.com
Thu Aug 18 10:24:30 CEST 2011


On Aug 17, 3:16 pm, Hans Mulder <han... at xs4all.nl> wrote:
> On 17/08/11 10:03:00, peter wrote:
>
> > Is there an equivalent to msvcrt for Linux users?  I haven't found
> > one, and have resorted to some very clumsy code which turns off
> > keyboard excho then reads stdin. Seems such an obvious thing to want
> > to do I am surprised there is not a standard library module for it. Or
> > have I missed someting (wouldn't be the first time!)
>
> The quick and dirty way is to invoke stty(1) using os.system:
>
> import os
>
> def getpassword(prompt="Password: "):
>      try:
>          os.system("stty -echo")
>          passwd = raw_input(prompt)
>      finally:
>          os.system("stty echo")
>      return passwd
>
> Strictly speaking, os.system is deprecated and you should use
> the equivalent invocation of subprocess.call:
>
> import subprocess
>
> def getpassword(prompt="Password: "):
>      try:
>          subprocess.call(["stty", "-echo"])
>          passwd = raw_input(prompt)
>      finally:
>          subprocess.call(["stty", "echo"])
>      return passwd
>
> If you don't want to use an external process, use termios:
>
> import termios, sys
>
> def getpassword(prompt="Password: "):
>      fd = sys.stdin.fileno()
>      old = termios.tcgetattr(fd)
>      new = termios.tcgetattr(fd)
>      new[3] = new[3] & ~termios.ECHO          # lflags
>      try:
>          termios.tcsetattr(fd, termios.TCSADRAIN, new)
>          passwd = raw_input(prompt)
>      finally:
>          termios.tcsetattr(fd, termios.TCSADRAIN, old)
>      return passwd
>
> These functions work on any Posix system (including Mac OSX),
> but not on Windows.
>
> Hope this helps,
>
> -- HansM

This is very similar to my solution, which was to use stty turn off
keyboard echo, then repeatedly read sys.stdin.read(1) until a unique
keystroke had been defined. For example, the 'Insert' key seems to
return a sequence of four codes, namely 27, 91, 50, 126.  It works but
has two disadvantages which I have managed to live with:-

1. As character 27 is used to signal the start of a 'special' key
sequence, it cannot detect a single press of the Esc key. The
workaround is to detect a double press instead.

2. Some keys seem to return different sets of codes depending on the
circumstances.  For example, F1 returns 27,91,91,65 from the command
line, and 27,79,80 from a GUI window. I suspect there may be
variations between flavours of Linux too. The solution is to detect
all possibilities - so far I haven't found any overlaps.

Not pretty, but as I said it works. I know now not to spend time
looking further. Whilst there may be a historical reason for the
current situation, it would be a great convenience for amateur coders
like mayself if the gurus could devise a platform independent version
of mscvrt.

If anyone is interested in the code I can post it, but it's quite long
as it comprises multiple if statements to cover each combination.

Peter



More information about the Python-list mailing list