remove last STDOUT line in Python

Question:

I am trying to figure out how to suppress the display of user input on stdout.

raw_input() followed by any print statement preserves what the user typed in. getpass() does not show what the user typed, but it does preserve the “Password:” prompt.

To fix this, I would like to only remove the last line (which would remove the newline from the end of the line as well).

Asked By: javanix

||

Answers:

You might be able to do what you want with VT100 control codes.

Something like this maybe:

CURSOR_UP_ONE = 'x1b[1A'
ERASE_LINE = 'x1b[2K'
print(CURSOR_UP_ONE + ERASE_LINE)

I am not entirely sure if this works: maybe you could, just before calling raw_input(), replace sys.stdout with your self-defined file-like object which swallows the output. Right after that, you could set sys.stdout back to what it has been before.

Edit: looks like this approach does not work, because whatever the user types in stays on the screen.

Another option for console manipulation and direct keyboard control is curses.

If what you’re doing is reading a password, use getpass. There are a lot of subtle gotchas involved in reading a password safely; it’s not code you want to write yourself.

If you are doing something less security-critical, disabling terminal echo can be done with the termios module. (I wish the example code there wasn’t an incomplete, unsafe implementation of getpass, sigh. But it does show you how to turn off terminal echo.)

If you’re on Windows, there is an equivalent but I don’t know what it is, and it may not be exposed in the Python standard library.

Answered By: zwol

The following code, based on the Python docs, uses the termios module and seems to do what you want (although it is not as compact as VT100 control codes):

def getpass(prompt="Password: "):
    import termios, sys
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    new = termios.tcgetattr(fd)
    new[3] = new[3] & ~termios.ECHO
    try:
        termios.tcsetattr(fd, termios.TCSADRAIN, new)
        passwd = raw_input(prompt)
        print 'r          r',
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old)
    return passwd

p = getpass()

There are two tricky lines: one disables the echo, the other one erases your password prompt remaining at the first position of the line.

Answered By: Vicent

Give this a try:

CURSOR_UP = '33[F'
ERASE_LINE = '33[K'
print(CURSOR_UP + ERASE_LINE)
Answered By: Ohad Cohen
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.