Terminal – Prevent Terminal Prompt from Being Overwritten by Program Output

ncursespromptterminal

Suppose I run a command like this in the terminal:

~$ echo 'sleep 2; echo "hello!"' | sh

then start typing the next line. After two seconds the words "hello!\n" will be inserted into whatever I'm writing. I know there is a workaround to this (pressing up then down which refreshes the prompt), however on other systems that don't have history—eg, using a MUD through telnet—this is not possible.

Does anybody know of an ncurses app or terminal emulator that separates stdin from stdout? This seems pretty easy to make in ncurses, you just have to use some clever dup2s, but before I make it I want to know if someone has done it before.

Any other solutions to the main problem are welcome, as well.

Best Answer

This isn't as easy as it sounds to change. It's related to the terminal cooked vs. raw mode and whether echo is enabled or not.

When the terminal is in cooked mode (the default), the kernel reads everything that comes in as input and processes it using rudimentary line editing capabilities which include echoing normal text immediately, processing the erase and kill characters which erase a single character and the whole of the current line respectively, and a few other things. Lines of text only actually appear on the terminal's input when you press enter. During the whole time up until you press enter, everything happens entirely inside the kernel and no process running on the terminal receives a single byte, therefore the foreground application doesn't even know that the user is in the process of typing anything. A process running on the tty cannot suppress this echo even if it wants to just because the echo would come at an inopportune time (e.g. intermixed with output) because such a process is not even aware that the input is happening.

You can set the terminal to raw mode instead with no echo to suppress this (stty raw, or with termios), but then you lose the kernel's line editing capabilities completely — which means for example that you cannot correct a typo by pressing Ctrl-u and starting over. More importantly, you will have a lot of trouble using any program that depends on the kernel's cooked processing (basically anything that doesn't use readline or ncurses) because you will be typing completely blind at such programs! Oh, and also: without the terminal cooked processing you lose the kernel's interception of job control shortcuts to interrupt and suspend (by default Ctrl-c and Ctrl-z respectively).

Related Question